1. 程式人生 > >hdu 6434 ( Problem I. Count )

hdu 6434 ( Problem I. Count )

otto name 技術 bottom 技術分享 lines print 分享 init

Problem I. Count

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 418 Accepted Submission(s): 216


Problem Description

Multiple query, for each n, you need to get
n i-1
∑ ∑ [gcd(i + j, i - j) = 1]
i=1 j=1


Input

On the first line, there is a positive integer T, which describe the number of queries. Next there are T lines, each line give a positive integer n, as mentioned above.
T<=1e5, n<=2e7


Output

Your output should include T lines, for each line, output the answer for the corre- sponding n.


Sample Input

4 978 438 233 666


Sample Output

194041 38951 11065 89963

a=i-j,所以i+j=2*i-a,那麽原式可以化簡為:

技術分享圖片

a一定是奇數。

1 歐拉函數的幾個性質:f(n) :歐拉函數值
2 1.若a為質數,phi[a]=a-1
; 3 2.若a為質數,b mod a=0,phi[a*b]=phi[b]*a 4 3.若a,b互質,phi[a*b]=phi[a]*phi[b](當a為質數時,if b mod a!=0 ,phi[a*b]=phi[a]*phi[b]) 5 4.gcd(kx,ky)=gcd(x,y)==1 6 5.gcd(kx-y,y)=gcd(kx,y)=gcd(x,y)==1 7 6.若N為奇數,那麽f(2*n)=2*f(n) 8 7.若n是質數p的k次冪,f(n)=p^k-p^(k-1)=(p-1)*p^(k-1) 9 因為除了p的倍數外,其他數都跟n互質。:1~n 每隔p個出現一個p的倍數

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<vector>
 7 #define N 20000009
 8 using namespace std;
 9 #define ll long long 
10 int pre[N],phi[N];
11 ll sum[N];
12 bool vis[N];
13 int t,n;
14 //歐拉函數 :phi[i] j:(1~i)裏有phi[i]個數令gcd(i,j)=1
15 void init()
16 {
17     pre[1]=1;
18     int i,j;
19     int pree=0;
20     for(i=2;i<=N;i++)
21     {
22         if(!vis[i]){
23             pre[++pree]=i;
24             phi[i]=i-1;
25         }
26         for(j=1;j<=pree&&i*pre[j]<=N;j++){
27             vis[i*pre[j]]=1;
28             if(i%pre[j]==0){
29                 phi[i*pre[j]]=phi[i]*pre[j];
30                 break;
31             }
32             else{
33                 phi[i*pre[j]]=phi[i]*phi[pre[j]];
34             }
35         }
36     }
37     for(int i=1;i<=N;i++){
38         if(i&1) phi[i]>>=1;          
39         sum[i]=sum[i-1]+phi[i];//求個前綴和即可
40         //if(i&1) phi[i]>>=1;
41         //因為a一定是奇數,那麽偶數不變,因為偶數與偶數的gcd一定!=1
42         //奇數減半 如 7 : 1 2 3 4 5 6  而只有1 3 5 有效
43     }
44 }
45 int main()
46 {  
47     init();
48     scanf("%d",&t);
49     while(t--){
50         scanf("%d",&n);
51         printf("%lld\n",sum[n]);
52     }
53     return 0;
54 }

hdu 6434 ( Problem I. Count )