EntropyIncreaser

LOJ6229 这是一道简单的数学题

Jan 17th, 2018
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.50 KB | None | 0 0
  1. #include <cmath>
  2. #include <cstdio>
  3.  
  4. #define LOG(FMT...) fprintf(stderr, FMT)
  5.  
  6. using namespace std;
  7.  
  8. const int N = 1e9 + 10, N23 = 1e6 + 10;
  9.  
  10. typedef long long ll;
  11.  
  12. struct gter {
  13.     int a[N23], b[N23];
  14.  
  15.     const int& operator[](int k) const {
  16.         return k < N23 ? a[k] : b[N / k];
  17.     }
  18.  
  19.     int& operator[](int k) {
  20.         return k < N23 ? a[k] : b[N / k];
  21.     }
  22. };
  23.  
  24. const int P = 1e9 + 7, REV2 = 500000004, REV3 = 333333336,
  25.           REV6 = (ll)REV2 * REV3 % P;
  26.  
  27. int n, n23, pc;
  28. bool vis[N23];
  29. int f[N23], g[N23], mu[N23], minp[N23];
  30. int p[N23];
  31. gter sf, sg, smu;
  32.  
  33. void euler();
  34. void dyh();
  35.  
  36. int sq(int x) { return (ll)x * x % P; }
  37. int sum1(int x) { return (ll)x * (x + 1) % P * REV2 % P; }
  38. int sum2(int x) { return (ll)x * (x + 1) % P * (2 * x % P + 1) % P * REV6 % P; }
  39.  
  40. int main() {
  41.     int ans = 0;
  42.     scanf("%d", &n);
  43.     n23 = pow(n, 2. / 3);
  44.     euler();
  45.     dyh();
  46.    
  47.     for (int l = 1, r; l <= n; l = r + 1) {
  48.         r = n / (n / l);
  49.         ans = (ans + (ll)P + (ll)(sf[r] - sf[l - 1]) % P * sq(sum1(n / l)) % P) % P;
  50.     }
  51.     ans = (ans + n) % P * (ll)REV2 % P;
  52.     printf("%d\n", ans);
  53.     return 0;
  54. }
  55.  
  56. void euler() {
  57.     mu[1] = 1;
  58.     f[1] = 1;
  59.     g[1] = 1;
  60.     for (int x = 2; x <= n23; ++x) {
  61.         if (!vis[x]) {
  62.             p[++pc] = x;
  63.             mu[x] = P - 1;
  64.             g[x] = (ll)(P - 1) * sq(x) % P;
  65.             f[x] = (1 + g[x]) % P;
  66.             minp[x] = x;
  67.         }
  68.         for (int i = 1; x * p[i] <= n23; ++i) {
  69.             int ind = x * p[i];
  70.             vis[ind] = true;
  71.             if (x % p[i] == 0) {
  72.                 // g[ind] = 0;
  73.                 // mu[ind] = 0;
  74.                 minp[ind] = minp[x] * p[i];
  75.                 if (minp[ind] != ind)
  76.                     f[ind] = (ll)f[ind / minp[ind]] * f[minp[ind]] % P;
  77.                 else
  78.                     f[ind] = f[x];
  79.                 break;
  80.             } else {
  81.                 minp[ind] = p[i];
  82.                 mu[ind] = (P - mu[x]) % P;
  83.                 g[ind] = (ll)g[x] * g[p[i]] % P;
  84.                 f[ind] = (ll)f[x] * f[p[i]] % P;
  85.             }
  86.         }
  87.     }
  88.     for (int i = 1; i <= n23; ++i) {
  89.         sf[i] = (sf[i - 1] + f[i]) % P;
  90.         sg[i] = (sg[i - 1] + g[i]) % P;
  91.         smu[i] = (smu[i - 1] + mu[i]) % P;
  92.     }
  93. }
  94.  
  95. void dyh() {
  96.     for (int l0 = n23 + 1, r0; l0 <= n; l0 = r0 + 1) {
  97.         r0 = n / (n / l0);
  98.         smu[r0] = 1;
  99.         sg[r0] = 1;
  100.         for (int l = 2, r; l <= r0; l = r + 1) {
  101.             r = r0 / (r0 / l);
  102.             smu[r0] = (smu[r0] - (r - l + 1) * (ll)smu[r0 / l] % P) % P;
  103.             if (smu[r0] < 0)
  104.                 smu[r0] += P;
  105.             sg[r0] = (sg[r0] - (ll)(P + sum2(r) - sum2(l - 1)) % P * sg[r0 / l] % P);
  106.             if (sg[r0] < 0)
  107.                 sg[r0] += P;
  108.         }
  109.         sf[r0] = sg[r0];
  110.         for (int l = 2, r; l <= r0; l = r + 1) {
  111.             r = r0 / (r0 / l);
  112.             sf[r0] = (P + sf[r0] - (ll)(smu[r] - smu[l - 1]) % P * sf[r0 / l] % P) % P;
  113.         }
  114.     }
  115. }
Advertisement
Add Comment
Please, Sign In to add comment