1. 程式人生 > >bzoj2705: [SDOI2012]Longge的問題

bzoj2705: [SDOI2012]Longge的問題

scan names color amp main space 它的 log spa

嗯A了道水題(其實在學polya的時候做過類似的)

題意很裸,就是求sigma(gcd(i,n)),那很容易發現很多i和n的gcd是相等的,那我們就枚舉gcd,然後將它的phi求出來,那(n/i)*phi(i)就將全部gcd為(n/i)的值給求出來了,同理phi(n/i)也一樣,那先預處理一下素數,然後O(sqrt(n))枚舉就行了。

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
bool v[1100000];
int pr,prime[1100000]; void linear_prime() { memset(v,true,sizeof(v)); for(int i=2;i<=1000000;i++) { if(v[i]==true)prime[++pr]=i; for(int j=1;j<=pr&&i*prime[j]<=1000000;j++) { v[i*prime[j]]=false; if(i%prime[j]==0)break; } } } LL n; LL phi(LL x) { LL ans
=x; for(int i=1;prime[i]*prime[i]<=x;i++) { if(x%prime[i]==0) { ans=ans-ans/prime[i]; while(x%prime[i]==0)x/=prime[i]; } } if(x!=1)ans=ans-ans/x; return ans; } int main() { linear_prime(); scanf("%lld",&n); LL ans
=0; for(int i=1;i*i<=n;i++)//枚舉gcd { if(n%i==0) { ans+=phi(i)*(n/i); if(i*i!=n)ans+=phi(n/i)*i; } } printf("%lld\n",ans); return 0; }

bzoj2705: [SDOI2012]Longge的問題