Longge's problem
Description
Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N.
"Oh, I know, I know!" Longge shouts! But do you know? Please solve it.
"Oh, I know, I know!" Longge shouts! But do you know? Please solve it.
Input
Input contain several test case.
A number N per line.
A number N per line.
Output
For each N, output ,∑gcd(i, N) 1<=i <=N, a line
Sample Input
2 6
Sample Output
3 15
Source
POJ Contest,Author:Mathematica@ZSU
思路:比如一个数n;
n跟一个数的gcd为k;
即求phi(n/k);
#include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> using namespace std; #define ll __int64 #define mod 1000000007 #define inf 999999999 //#pragma comment(linker, "/STACK:102400000,102400000") int scan() { int res = 0 , ch ; while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) ) { if( ch == EOF ) return 1 << 30 ; } res = ch - '0' ; while( ( ch = getchar() ) >= '0' && ch <= '9' ) res = res * 10 + ( ch - '0' ) ; return res ; } #define MAXN 100001 ll prime[MAXN];//保存素数 ll vis[MAXN],ji;//初始化 ll Prime(ll n) { ll cnt=0; //memset(vis,0,sizeof(vis)); for(ll i=2;i<=n;i++) { if(!vis[i]) prime[cnt++]=i; for(ll j=0;j<cnt&&i*prime[j]<n;j++) { vis[i*prime[j]]=1; if(i%prime[j]==0)//关键 break; } } return cnt; } ll phi(ll n) { ll i,rea=n; for(i=0;i<ji;i++) { if(prime[i]*prime[i]>n)break; if(n%prime[i]==0) { rea=rea-rea/prime[i]; while(n%prime[i]==0) n/=prime[i]; } } if(n>1) rea=rea-rea/n; return rea; } int main() { ll x,y,z,i,t; ji=Prime(52010); while(~scanf("%I64d",&x)) { ll ans=0; for(i=1;i*i<=x;i++) { if(x%i==0) { ll gg=i; ll hh=x/i; ans+=gg*phi(hh); if(hh!=gg) ans+=hh*phi(gg); } } printf("%I64d\n",ans); } return 0; }