bzoj2705Longge的问题
题意很简单
$$ans=\sum_{i=1}^{n}gcd(i,n)$$
然后推一下式子,求一下欧拉函数就好了
细节是由于$BZOJ$的评测计时策略,
不能线性筛啊$……$
必须每个数单独筛
一开始线性筛洛谷上过了,$BZ$果断$T$
/************************************************************** Problem: 2705 User: zhangheran Language: C++ Result: Accepted Time:28 ms Memory:89184 kb ****************************************************************/ #pragma GCC optimize (2) #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int cnt; int prime[10000010]; int phi[10000010]; bool ins[10000010]; void Euler() { phi[1]=1; for(int i=2;i<=10000000;i++){ if(!ins[i]) prime[++cnt]=i,phi[i]=i-1; for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++){ ins[i*prime[j]]=true; if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;} else phi[i*prime[j]]=phi[i]*(prime[j]-1); } } return ; } long long getphi(long long n) { // if(n<10000000) return phi[n]; long long res=n; for(long long i=2;i*i<=n;i++){ if(n%i==0) res=res/i*(i-1); while(n%i==0) n/=i; } if(n>1) res=res/n*(n-1); return res; } long long x; long long ans; int main() { // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); scanf("%lld",&x); // Euler(); long long i=1; for(;i*i<x;i++) if(x%i==0) ans+=i*getphi(x/i)+(x/i)*getphi(i); if(i*i==x) ans+=i*getphi(i); printf("%lld",ans); } //9812