Main topic:
Give a range [1,n], find out two numbers x, Y, make gcd (x, y) a prime number, ask how many pairs (x, y order)
Solution:
Not difficult, Euler function practiced hand problem, you can define the set P ={x|x to prime, then we enumerate gcd (x, y) may be equal to the case, for any p∈p can be obtained: gcd (k1 p,k2 p) = p, when and only if gcd (k1,k2) = 1; Then we just have to enumerate all the K1,K2. You can set K1>K2, then the number of given K1,k2 is Phi (K1), because ordered, so to phi*2, but, whether this leakage? Yes, let's go and fill it out, so the answer is to calculate the expression below.
People with a bit of common sense will see that if our tank is further (foggy) to calculate the equation, the complexity is O (n^2), we analyze the complexity of the main consumption where.
1. Calculate PHI
If we use the brute force formula, that is, the complexity is obviously very high, it all comes up (not the Gundam)O (N*SQRT (n)), and the complexity is intolerable within 1e7, so we
You have to do something else, I'm going to introduce three very powerful things:
1. When P∈p, phi (P) = p-1;
2. If I mod p = 0, then phi (i * p) =p * PHI (i), prove slightly, in fact, I will not testify
3. If I mod p≠0, then phi (i * p) =phi (i) * (p-1);
With these three, it is easy to write a linear Euler function.
2. Double cycle
Inside that heavy loop can be pushed out of the outside, think, or look at my code.
Then the complexity of this is reduced to O (n);
3. Here is the code
1#include <bits/stdc++.h>2 using namespacestd;3 intflag[10000001],p[6000000],tot;4 intphi[10000001];5 voidGet_p (intend) {6 for(intI=1; i<=end;i++)7Flag[i] =1;8 for(intI=2; i<=end; i++){ 9 if(flag[i]==1){Tenp[++tot]=i; OnePhi[i] = i1; A } - for(intj=1; J<=tot && p[j]*i<=end; J + +){ -flag[p[j]*i]=0; the if(i%p[j]==0){ -PHI[I*P[J]] = p[j] * Phi[i];//characteristics of Euler functions - Break; -}ElsePHI[I*P[J]] = (p[j]-1) *Phi[i]; + } - } + } A Long Longf[10000001]; at - intMain () { - intN; -CIN >>N; - get_p (n); -f[1] =1; in for(intI=2; i<=n;i++){ -F[i] = f[i-1] +phi[i]*2; to } + Long LongAns =0; - for(intI=1; i<=tot;i++){ theAns = ans+f[n/P[i]]; * } $cout<<ans;Panax Notoginseng return 0; -}
BZOJ2818 GCD "Euler function, linear sieve"