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 }
原文地址:https://www.cnblogs.com/tingtin/p/9522956.html
时间: 2024-11-12 22:56:45