LG5218 无聊的水题

无聊的水题

DLS 是一个喜欢玩游戏的男生。

今天他从朋友那里看到了 \(n\) 件武器,其中第 \(i\) 件武器的威力值为 \(i\)

他观察了这 \(n\) 件武器许久,打算买下其中若干件武器,但他想用买下的武器的威力值组合出任意威力值,其中每一件武器已经的威力值可以叠加,甚至可以减去。

例如一个威力值为 \(3\) 的武器,可以组合成的威力值为 \(\dots,-6,-3,0,3,6,\dots\)

他想找出所有满足以上条件的买下装备的方案,但方案数量实在太多了。你能帮他计算一下吗?答案对 \(10^9+7\) 取模。

\(n \leq 10^{11}\)

题解

https://www.alpha1022.me/articles/lg-5218.htm

使用结合律证明裴蜀定理对三个及以上的元素有效。所以问题转化为有多少种选数的方案使得选出的数的 \(\gcd = 1\)

\(f(x)\) 表示使得选出的数的 \(\gcd=x\) 的方案数。那么答案就是 \(f(1)\)

\(F(x)\) 表示使得选出的数的 \(\gcd\)\(x\) 的倍数的方案数。那么有

\[ F(x)=2^{\lfloor n/x\rfloor}-1\\ F(x)=\sum_{x|y}f(y) \]

出现了莫比乌斯反演不常见的第二种形式。

\[ f(x)=\sum_{x|y}\mu\left(\frac{y}{x}\right)F(y) \]

这也不是狄利克雷卷积,看起来没法做。解决办法是直接代入 \(f(1)\)

\[ f(1)=\sum_{i=1}^n\mu(i)F(i)\\ =\sum_{i=1}^n\mu(i)(2^{\lfloor n/i\rfloor}-1) \]

对于指数做数论分块,对于 \(\mu\) 杜教筛就好了。

时间复杂度 \(O(n^{2/3})\)

CO int N=1e7+10;
int pri[N],tot,mu[N];
int64 n;
int sum[N];

int calc(int64 n){
    if(n<N) return mu[n];
    if(sum[::n/n]) return sum[::n/n];
    int ans=1;
    for(int64 l=2,r;l<=n;l=r+1){
        r=n/(n/l);
        ans=add(ans,mod-mul((r-l+1)%mod,calc(n/l)));
    }
    return sum[::n/n]=ans;
}
int main(){
    mu[1]=1;
    for(int i=2;i<N;++i){
        if(!pri[i]) pri[++tot]=i,mu[i]=mod-1; // edit 1: mod-1
        for(int j=1;j<=tot and i*pri[j]<N;++j){
            pri[i*pri[j]]=1;
            if(i%pri[j]==0) break;
            mu[i*pri[j]]=mod-mu[i];
        }
    }
    for(int i=1;i<N;++i) mu[i]=add(mu[i],mu[i-1]);
    read(n);
    int ans=0;
    for(int64 l=1,r;l<=n;l=r+1){
        r=n/(n/l);
        ans=add(ans,mul(add(calc(r),mod-calc(l-1)),fpow(2,n/l%(mod-1))-1));
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/12175297.html