BZOJ3512 DZY Loves Math IV

解:这又是什么神仙毒瘤题......

我直接把后面那个phi用phi * I = id反演一波,得到个式子,然后推不动了......

实际上第一步我就大错特错了。考虑到n很小,我们有

BZOJ3512 DZY Loves Math IV

然后计算S,我们根据欧拉函数的性质有:

BZOJ3512 DZY Loves Math IV

于是只考虑n sqr free的情况。

到这里有两种解法,一种是暴力递归。

BZOJ3512 DZY Loves Math IV

考虑n的一个因子p,我们先提取出前面那一项,但是这还不够。因为当p|i的时候应该提出来p = phi[p] + 1。

于是我们在后面补上。令i = pt,就有了递归式。

  1 #include <cstdio>
  2 #include <map>
  3 
  4 typedef long long LL;
  5 const int N = 1000010, T = 1000008;
  6 const LL MO = 1e9 + 7, INF = 0x7f7f7f7f7f7f7f7fll;
  7 
  8 int phi[N], p[N], top, last[N];
  9 LL Phi[N], inv2;
 10 bool vis[N];
 11 
 12 namespace Hash {
 13     struct Node {
 14         LL val, ans;
 15         int nex;
 16         Node(LL x = 0, LL y = 0, int z = 0) {
 17             val = x;
 18             ans = y;
 19             nex = z;
 20         }
 21     }node[20000010]; int top;
 22     const int mod = 20000000;
 23     int e[mod];
 24     inline void insert(LL p, LL v) {
 25         int x = p % mod;
 26         node[++top] = Node(p, v, e[x]);
 27         e[x] = top;
 28         return;
 29     }
 30     inline LL find(LL p) {
 31         int x = p % mod;
 32         for(int i = e[x]; i; i = node[i].nex) {
 33             if(node[i].val == p) return node[i].ans;
 34         }
 35         return -INF;
 36     }
 37 }
 38 
 39 inline void getp(int n) {
 40     phi[1] = 1;
 41     for(int i = 2; i <= n; i++) {
 42         if(!vis[i]) {
 43             p[++top] = i;
 44             phi[i] = i - 1;
 45             last[i] = i;
 46         }
 47         for(int j = 1; j <= top && i * p[j] <= n; j++) {
 48             vis[i * p[j]] = 1;
 49             last[i * p[j]] = p[j];
 50             if(i % p[j] == 0) {
 51                 phi[i * p[j]] = phi[i] * p[j];
 52                 break;
 53             }
 54             phi[i * p[j]] = phi[i] * (p[j] - 1);
 55         }
 56     }
 57     for(int i = 1; i <= n; i++) {
 58         Phi[i] = (Phi[i - 1] + phi[i]) % MO;
 59     }
 60     return;
 61 }
 62 
 63 LL getPhi(LL x) {
 64     if(x <= 0) return 0;
 65     if(x <= T) return Phi[x];
 66     LL temp = Hash::find(x);
 67     if(temp != -INF) return temp;
 68     //printf("getPhi %lld T = %d\n", x, T);
 69     LL ans = (x % MO) * ((x + 1) % MO) % MO * inv2 % MO;
 70     for(LL i = 2, j; i <= x; i = j + 1) {
 71         j = x / (x / i);
 72         ans -= ((j - i + 1) % MO) * getPhi(x / i) % MO;
 73         ans = (ans % MO + MO) % MO;
 74     }
 75     Hash::insert(x, ans);
 76     return ans;
 77 }
 78 
 79 LL S(LL n, LL m) {
 80     //printf("S : %lld %lld \n", n, m);
 81     if(n == 1) return getPhi(m);
 82     if(m == 0) return 0;
 83     if(m == 1) return phi[n];
 84     LL p = last[n];
 85     LL ans = (phi[p] * S(n / p, m) % MO + S(n, m / p)) % MO;
 86     return ans;
 87 }
 88 
 89 int main() {
 90     inv2 = (MO + 1) / 2;
 91     getp(T);
 92     LL nn, m;
 93     scanf("%lld%lld", &nn, &m);
 94     LL ans = 0;
 95     for(int i = 1; i <= nn; i++) {
 96         LL p = 1, q = 1, n = i;
 97         while(n > 1) {
 98             LL temp = last[n];
 99             p *= temp;
100             n /= temp;
101             while(n % temp == 0) {
102                 n /= temp;
103                 q *= temp;
104             }
105         }
106         ans = (ans + q * S(p, m) % MO) % MO;
107     }
108     printf("%lld\n", ans);
109     return 0;
110 }
TLE

相关文章:

  • 2021-11-23
  • 2022-12-23
  • 2022-02-19
  • 2022-01-30
  • 2021-10-07
  • 2021-06-05
  • 2021-09-11
  • 2022-01-12
猜你喜欢
  • 2021-11-11
  • 2022-02-03
  • 2021-10-14
  • 2021-07-21
  • 2022-02-02
  • 2021-05-25
相关资源
相似解决方案