zoukankan      html  css  js  c++  java
  • luogu p4240 毒瘤之神的考验

    题意 : 求 \(\sum_{i=1}^{N}{\sum_{j=1}^{M}{\phi(ij)}}; N,M \leq 10^5, q \leq 10^4\)

    \(N \leq M\).

    根据\(\phi\)的性质 可以得到\(\phi(ij)=\frac{\phi(i)\phi(j)gcd(i,j)}{\phi(gcd(i,j))}\)

    如果这一步没想到,只能说是莫反做的不够多了...

    \(nm\)过大的情况下是没法处理乘积的,而且直接这么看也看不出什么性质来

    所以考虑把乘在一起的\(ij\)分开处理。

    于是 \(\sum_{i=1}^{N}{\sum_{j=1}^{M}{\phi(ij)}} = \sum_{i=1}^{N}{\sum_{j=1}^{M}{\frac{\phi(i)\phi(j)gcd(i,j)}{\phi(gcd(i,j))}}}\),

    \(gcd(i,j)\)相关提出来 可以得到

    \(\sum_{i=1}^{N}{\sum_{j=1}^{M}{\frac{\phi(i)\phi(j)gcd(i,j)}{\phi(gcd(i,j))}}}=\sum_{d=1}^{N}{\frac{d}{\phi(d)}\sum_{i=1}^{N/d}{\sum_{j=1}^{M/d}{\phi(id)\phi(jd)}{\sum_{e|gcd(i,j)}{\mu(e)}}}}\)

    常规性地开始枚举\(e\) 得到 \(\sum_{d=1}^{N}{\frac{d}{\phi(d)}\sum_{e=1}^{N/d}{\mu(e){\sum_{i=1}^{N/de}{\sum_{j=1}^{M/de}{\phi(ide)\phi(jde)}}}}}\)

    习惯性地枚举\(de\) 得到 \(\sum_{T=1}^{N}{\sum_{i=1}^{N/T}{\phi(iT)\sum_{j=1}^{M/T}{\phi(jT)}}\sum_{d|T}{\phi(\frac{T}{d})\frac{d}{\phi(d)}}}\)

    \(f(T)=\sum_{d|T}{\phi(\frac{T}{d})\frac{d}{\phi(d)}}\) , \(G(N,T)=\sum_{i=1}^{N}{\phi(iT)}\), 代入上式得 :

    \(\sum_{T=1}^{N}{\sum_{i=1}^{N/T}{\phi(iT)\sum_{j=1}^{M/T}{\phi(jT)}}\sum_{d|T}{\phi(\frac{T}{d})\frac{d}{\phi(d)}}}=\sum_{T=1}^{N}{G(N/T,T)G(M/T,T)f(T)}\)

    \(S(n,i,j)=\sum_{T=1}^{n}G(iT,T)G(jT,T)f(T)\)

    那么设\(\lfloor{N/T}\rfloor==i,\lfloor{M/T}\rfloor==j\)\(N\)的最大值为\(up\),最小值为\(down\) 那么

    此时的\(ans=S(up,i,j) - S(down-1,i,j)\)

    因为上界是\(\lfloor{N/T}\rfloor\)所以\(G\)可以用\(NlnN\)内全部暴力预处理出来

    \(G(N,T)=G(N-1,T)+\phi(NT)\)

    可以预处理一部分\(S\), 其中\(S(N,i,j)=S(N-1,i,j)+G(iN,N)G(jN,N)f(N)\)

    经过计算(调参)可以得到上界\(B\)

    upd :为啥代码丢到LOJ上就挂的只剩下50了 , 求助。

    #include<cstdio>
    #include<cstring>
    #include<vector>
    
    const int N = 1e5 + 7;
    const int lim = 1e5;
    const int B = 35;
    typedef long long ll;
    const int p = 998244353;
    inline int max (int a, int b) {
      return a > b ? a : b;
    }
    inline int min (int a, int b) {
      return a > b ? b : a;
    }
    
    int isp[N], mu[N], phi[N], prime[N], pcnt;
    int *G[N], *S[B + 1][B + 1], f[N], inv[N];
    
    inline void init () {
      inv[1] = 1, mu[1] = 1, phi[1] = 1;
      for (int i = 2; i <= lim; i++) inv[i] = p - (ll)(p / i) * inv[p % i] % p;
      for (int i = 2; i <= lim; i++) {
        if (!isp[i]) phi[i] = i - 1, mu[i] = -1, prime[++pcnt] = i;
        for (int j = 1; j <= pcnt && prime[j] * i <= lim; j++) {
          isp[i * prime[j]] = 1;
          if (i % prime[j] == 0) {
            phi[i * prime[j]] = phi[i] * prime[j] % p, mu[i * prime[j]] = 0;
            break;
          }
          phi[i * prime[j]] = phi[i] * (prime[j] - 1) % p , mu[i * prime[j]] = -mu[i];
        }
      }
      for (int i = 1; i <= lim; i++) for (int j = 1; i * j <= lim; j++) {
          f[i * j] = (f[i * j] + (ll) ((ll)i * inv[phi[i]] % p) % p * mu[j] % p) % p;
        }
      for (int i = 1; i <= lim; i++) {
        int upmax = lim / i;
        G[i] = new int [upmax + 1];
        G[i][0] = 0;
        for (int j = 1; j <= upmax; j++) G[i][j] = (ll)((ll)G[i][j - 1] + (ll)phi[i * j]) % p;
      }
      for (int j = 1; j <= B; j++) for (int k = 1; k <= B; k++) {
          int upmax = (lim / max (j, k));
          S[j][k] = new int [upmax + 1];
          S[j][k][0] = 0;
          for (int i = 1; i <= upmax; i++) {
            S[j][k][i] = (ll)((ll)S[j][k][i - 1] + ll((ll)f[i] * G[i][j] % p * G[i][k])) % p;
          }
        }
    }
    int main () {
      int T;
      scanf ("%d", &T);
      init ();
      while (T--) {
        int n, m, tmp;
        scanf ("%d%d", &n, &m);
        if (n > m) tmp = n, n = m, m = tmp;
        ll ans = 0;
        for (int i = 1, upmax = m / B; i <= upmax; i++)
          ans = (ans + ((ll)f[i] * G[i][n / i] % p * G[i][m / i] % p)) % p;
        for (int l = m / B + 1, r; l <= n; l = r + 1) {
          r = min (n / (n / l), m / (m / l));
          ans = (ans + (ll(S[n / l][m / l][r] - S[n / l][m / l][l - 1]) % p + p) % p) % p;
        }
        printf ("%lld\n", ans);
      }
      return 0;
    }
    
  • 相关阅读:
    DOM
    JS方法
    边界与边框,列表与方块
    for 练习
    背景与前景温习
    AD域账号验证
    邮件发送案例
    获取每个月最后一天的小技巧
    SQL 执行顺序
    常用下载地址
  • 原文地址:https://www.cnblogs.com/cjc030205/p/11638069.html
Copyright © 2011-2022 走看看