poj 2480 数论

题意:求∑gcd(i, N) 1<=i <=N

 

思路:求出所有约数

欧拉函数

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 #define MAXN 10000
 8 long long Div[MAXN],prime[MAXN],factor[MAXN],l[MAXN],p[MAXN];
 9 bool use[70000];
10 long long n,m,top=0;
11 void make_prime()
12 {
13     memset(use,1,sizeof(use));
14     use[1]=0; use[0]=0;
15     int i,j;
16     for(i=2;i<300;i++)
17         if(use[i])
18             for(j=i*i;j<70000;j+=i)
19                 use[j]=0;
20     j=0;
21     for(i=2;i<70000;i++)
22         if(use[i])
23             prime[++j]=i;
24     m=j;
25 }
26 
27 long long divide(long long x,long long p[],long long prime[])
28 {
29     int i,j=0;
30     for(i=1;i<=m;i++)
31     {
32         if(x<prime[i]) break;
33         if(x%prime[i]!=0) continue;
34         p[++j]=prime[i];
35         l[j]=0;
36         while(x%prime[i]==0)
37         {
38             x/=prime[i];
39             l[j]++;
40         }
41     }
42     if(x!=1)
43     {
44         p[++j]=x;
45         l[j]=1;
46     }
47     return j;
48 }
49 void dfs(int t,long long x)
50 {
51     if(t==m+1)
52     {
53         factor[++top]=x;
54         return ;
55     }
56     dfs(t+1,x);
57     for(int i=1;i<=l[t];i++)
58         x=x*Div[t], dfs(t+1,x);
59 }
60 long long Euler(long long p[],long long m,long long n)
61 {
62     int i;
63     for(i=1;i<=m;i++)
64         n=n/p[i]*(p[i]-1);
65     return n;
66 }
67 void solve()
68 {
69     int i,m;
70     long long ans=0;
71     for(i=1;i<=top;i++)
72     {
73         m=divide(n/factor[i],p,Div);
74         ans+=factor[i]*Euler(p,m,n/factor[i]);
75     }
76     printf("%lld\n",ans);
77 }
78 int main()
79 {
80     int i,j;
81     make_prime();
82     while(scanf("%lld",&n)!=EOF)
83     {
84         m=6935;
85         top=0;
86         m=divide(n,Div,prime);
87         dfs(1,1);
88         solve();
89     }
90     return 0;
91 }

posted on 2012-05-21 14:47  myoi  阅读(221)  评论(0编辑  收藏  举报

导航