BZOJ2705: [SDOI2012]Longge的问题
Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Input
一个整数,为N。
Output
一个整数,为所求的答案。
Sample Input
6
Sample Output
15
HINT
【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
题解Here!
题目要求:$Ans=\sum_{i=1}^ngcd(i,n)$
这式子好眼熟啊——莫比乌斯反演。
然而只有一个求和符号。
那就习惯性地枚举$gcd(i,n)$!
即:$$Ans=\sum_{d|n}\sum_{i=1}^nd[gcd(i,n)==d]$$
提到前面来:$$Ans=\sum_{d|n}d\sum_{i=1}^n[gcd(i,n)==d]$$
把那个$d$同时消去:$$Ans=\sum_{d|n}d\sum_{i=1}^{\frac{n}{d}}[gcd(i,\frac{n}{d})==1]$$
由于$d|n$,所以$d$与$\frac{n}{d}$的性质是一样的,于是:$$Ans=\sum_{d|n}d\sum_{i=1}^d[gcd(i,d)==1]$$
我们要求小于$d$且与$d$互质的数的个数。
这是什么?
$\varphi(i)$函数!
于是:$$Ans=\sum_{d|n}d\times \varphi(d)$$
然而这次$N<=2^{32}$,所以不能线性筛了,只能暴力$O(\sqrt n)$枚举因数。
前面那个也是暴力$O(\sqrt n)$枚举因数。
所以总复杂度的上界是$O(n)$。
但是这个上界非常的松,所以总复杂度基本上也就$O(5\times 10^6)$的样子。。。
然后网上一堆神题解啊,本蒟蒻还是菜啊。。。
什么懵逼钨丝反演,甚至连$O(\sqrt n)$的算法,以及用$Pollard-rho$优化达到$O(\sqrt[4]n)$的算法都搞出来了。。。
真是百花齐放百家争鸣啊。。。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
inline long long read(){
long long date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
long long phi(long long n){
long long ans=n;
for(long long i=2LL;i*i<=n;i++)
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0)n/=i;
}
if(n>1)ans=ans/n*(n-1);
return ans;
}
long long solve(long long n){
long long ans=0,x=1LL;
for(;x*x<n;x++)if(n%x==0)ans+=x*phi(n/x)+(n/x)*phi(x);
if(x*x==n)ans+=x*phi(x);
return ans;
}
int main(){
long long n=read();
printf("%lld\n",solve(n));
return 0;
}

浙公网安备 33010602011771号