歐拉函數入門題...html
固然若是有興趣也能夠用反演作...相似這題ide
題意就是求,方陣從左下角出發能看到多少個點。函數
從0開始給座標spa
發現一個點能被看到,那麼橫縱座標互質。code
而後求歐拉函數的前綴和,* 2 + 1便可。htm
注意特判。blog
1 #include <cstdio> 2 const int N = 40010; 3 4 int p[N], phi[N], top; 5 bool vis[N]; 6 7 inline void getphi(int b) { 8 phi[1] = 1; 9 for(int i = 2; i <= b; i++) { 10 if(!vis[i]) { 11 p[++top] = i; 12 phi[i] = i - 1; 13 } 14 for(int j = 1; j <= top && i * p[j] <= b; j++) { 15 vis[i * p[j]] = 1; 16 if(i % p[j] == 0) { 17 phi[i * p[j]] = phi[i] * p[j]; 18 break; 19 } 20 phi[i * p[j]] = phi[i] * (p[j] - 1); 21 } 22 } 23 return; 24 } 25 26 int main() { 27 int n; 28 scanf("%d", &n); 29 if(n == 1) { 30 printf("0"); 31 return 0; 32 } 33 n--; 34 getphi(n); 35 int ans = 0; 36 for(int i = 1; i <= n; i++) { 37 ans += phi[i]; 38 } 39 ans = ans * 2 + 1; 40 printf("%d", ans); 41 42 return 0; 43 }
莫比烏斯反演:get
求n之內gcd == 1的數對個數。io
根據上面的方法搞一搞,最後 + 2便可。入門
也要特判。
1 #include <cstdio> 2 3 const int N = 40010; 4 5 int p[N], miu[N], top; 6 bool vis[N]; 7 8 inline void getmiu(int b) { 9 miu[1] = 1; 10 for(int i = 2; i <= b; i++) { 11 if(!vis[i]) { 12 p[++top] = i; 13 miu[i] = -1; 14 } 15 for(int j = 1; j <= top && i * p[j] <= b; j++) { 16 vis[i * p[j]] = 1; 17 if(i % p[j] == 0) { 18 break; 19 } 20 miu[i * p[j]] = -miu[i]; 21 } 22 } 23 return; 24 } 25 26 int main() { 27 int n; 28 scanf("%d", &n); 29 n--; 30 if(!n) { 31 printf("0"); 32 return 0; 33 } 34 getmiu(n); 35 36 int ans = 0; 37 for(int i = 1; i <= n; i++) { 38 ans += miu[i] * (n / i) * (n / i); 39 } 40 printf("%d", ans + 2); 41 return 0; 42 }