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;
}
静渊以有谋,疏通而知事。