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; }