EntropyIncreaser

Luogu3768 简单数学题

Dec 20th, 2017
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.04 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. typedef long long ll;
  9.  
  10. const int N = 5000010;
  11.  
  12. struct getter {
  13.     int& operator[](ll ind) const;
  14. } s;
  15.  
  16. int p, pc, r6, bd;
  17. ll n;
  18.  
  19. bool vis[N];
  20. int phi[N], sum[N], sum2[N], ps[1000010];
  21.  
  22. void euler();
  23. void du();
  24. int rev(int x);
  25. void ex_gcd(int a, int b, int& x, int& y);
  26. int sq(ll x);
  27. int s1(ll x);
  28. int s2(ll x);
  29. int s3(ll x);
  30.  
  31. int main() {
  32.     int ans = 0;
  33.     scanf("%d%lld", &p, &n);
  34.     r6 = rev(6);
  35.     bd = pow(n, 2. / 3);
  36.     euler();
  37.     du();
  38.     for (ll l = 1, r; l <= n; l = r + 1) {
  39.         r = n / (n / l);
  40.         ans = (ans + (ll)s3(n / l) * ((s[r] - s[l - 1]) % p) % p) % p;
  41.         if (ans < 0)
  42.             ans += p;
  43.     }
  44.     printf("%d\n", ans);
  45.     return 0;
  46. }
  47.  
  48. inline int sq(ll x) {
  49.     x %= p;
  50.     return x * x % p;
  51. }
  52.  
  53. inline int s1(ll x) {
  54.     x %= p;
  55.     return x * (x + 1) / 2 % p;
  56. }
  57.  
  58. inline int s3(ll x) {
  59.     return sq(s1(x));
  60. }
  61.  
  62. inline int s2(ll x) {
  63.     x %= p;
  64.     return x * (x + 1) % p * (x * 2 + 1) % p * r6 % p;
  65. }
  66.  
  67. int& getter::operator[](ll ind) const {
  68.     if (ind <= bd)
  69.         return sum[ind];
  70.     return sum2[n / ind];
  71. }
  72.  
  73. int rev(int a) {
  74.     int x, y;
  75.     ex_gcd(a, p, x, y);
  76.     if (x < 0)
  77.         x += p;
  78.     return x;
  79. }
  80.  
  81. void ex_gcd(int a, int b, int& x, int& y) {
  82.     if (b == 0) {
  83.         x = 1;
  84.         y = 0;
  85.         return;
  86.     }
  87.     ex_gcd(b, a % b, y, x);
  88.     y -= a / b * x;
  89. }
  90.  
  91. void euler() {
  92.     phi[1] = 1;
  93.     for (int i = 2; i <= bd; ++i) {
  94.         if (!vis[i]) {
  95.             ps[++pc] = i;
  96.             phi[i] = i - 1;
  97.         }
  98.         for (int j = 1; i * ps[j] <= bd; ++j) {
  99.             vis[i * ps[j]] = true;
  100.             if (i % ps[j] == 0) {
  101.                 phi[i * ps[j]] = phi[i] * ps[j];
  102.                 break;
  103.             } else
  104.                 phi[i * ps[j]] = phi[i] * (ps[j] - 1);
  105.         }
  106.     }
  107.     for (int i = 1; i <= bd; ++i)
  108.         sum[i] = (sum[i - 1] + (ll)sq(i) * phi[i]) % p;
  109. }
  110.  
  111. void du() {
  112.     for (ll l0 = bd, r0; l0 <= n; l0 = r0 + 1) {
  113.         r0 = n / (n / l0);
  114.         s[r0] = s3(r0);
  115.         for (ll l = 2, r; l <= r0; l = r + 1) {
  116.             r = r0 / (r0 / l);
  117.             s[r0] = (s[r0] - (ll)s[r0 / l] * ((s2(r) - s2(l - 1)) % p) % p) % p;
  118.             if (s[r0] < 0)
  119.                 s[r0] += p;
  120.         }
  121.     }
  122. }
Advertisement
Add Comment
Please, Sign In to add comment