浏览代码

欧拉函数打表求和

jal 5 年之前
父节点
当前提交
9842161762
共有 1 个文件被更改,包括 62 次插入0 次删除
  1. 62 0
      E.cpp

+ 62 - 0
E.cpp

@@ -0,0 +1,62 @@
+//
+// Created by jal on 2019-05-01.
+//
+
+#include <bits/stdc++.h>
+using namespace std;
+vector<int>primes = {2,3,5};
+vector<int>phi;
+void init(int n){
+    for(int i = primes.back()+2; i <= n; i+= 2){
+        bool flag = true;
+        for(auto p : primes){
+            if(p * p > i)break;
+            if(i % p == 0){
+                flag = false;
+                break;
+            }
+        }
+        if(flag)primes.push_back(i);
+    }
+}
+void genPhi(int max){
+    int minDiv[max];
+    for(int i = 1; i < max; i++){
+        minDiv[i] = i;
+    }
+    for(int i = 2; i * i < max; i++){
+        if(minDiv[i] == i){
+            for(int j = i*i; j < max; j += i){
+                minDiv[j] = i;
+            }
+        }
+    }
+    phi[1] = 1;
+    for(int i = 2; i < max; i++){
+        phi[i] = phi[i / minDiv[i]];
+        if((i / minDiv[i]) % minDiv[i] == 0){
+            phi[i] *= minDiv[i];
+        }else{
+            phi[i] *= minDiv[i] - 1;
+        }
+    }
+}
+int main(){
+    int n;
+    cin >> n;
+    init(n);
+    phi.resize(n+1);
+    genPhi(n+1);
+    vector<long long> sum(n/2+1, 0);
+    for(int i = 1; i <= n/2; i++){
+        sum[i] = sum[i-1] + phi[i];
+    }
+    long long cnt = 0;
+    for(auto i : primes){
+        cnt += phi[1];
+        if(n / i != 1){
+            cnt += 2 * (sum[n/i] - phi[1]);
+        }
+    }
+    cout << cnt << endl;
+}