P4240 毒瘤之神的考验

P4240 毒瘤之神的考验

求:

i=1nj=1mφ(ij)\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(ij)

先要考虑怎么把 φ\varphi 转成带有 gcd\gcdlcm\operatorname{lcm} 的形式。

性质:φ(ij)=φ(i)φ(j)gcd(i,j)φ(gcd(i,j))\varphi(ij)=\frac{\varphi(i)\varphi(j)\gcd(i,j)}{\varphi(\gcd(i,j))}

证明:

φ(i)φ(j)=ipip1pjpjp1ppprimes=ijpijp1ppgcd(i,j)p1p\begin{aligned} \varphi(i)\varphi(j)&=i\prod_{p|i}\frac{p-1}{p}j\prod_{p|j}\frac{p-1}{p} &p\in \text{primes}\\ &=ij\prod_{p|ij}\frac{p-1}{p}\prod_{p|\gcd(i,j)}\frac{p-1}{p} \end{aligned}

所以有:

φ(i)φ(j)gcd(i,j)=ijpijp1pgcd(i,j)pgcd(i,j)p1p=φ(ij)φ(gcd(i,j))\begin{aligned} \varphi(i)\varphi(j)\gcd(i,j)&=ij\prod_{p|ij}\frac{p-1}{p}\gcd(i,j)\prod_{p|\gcd(i,j)}\frac{p-1}{p}\\ &=\varphi(ij)\varphi(\gcd(i,j)) \end{aligned}

化简式子,有:

i=1nj=1mφ(ij)=i=1nj=1mφ(i)φ(j)gcd(i,j)φ(gcd(i,j))=d=1ndφ(d)i=1nj=1mφ(i)φ(j)[gcd(i,j)=d]=d=1ndφ(d)i=1ndj=1mdφ(id)φ(jd)[gcd(i,j)=1]=d=1ndφ(d)p=1ndμ(p)i=1ndφ(id)[pi]j=1mdφ(jd)[pj]=d=1ndφ(d)p=1ndμ(p)i=1nkdφ(ikd)j=1mkdφ(jkd)=T=1n(dTdφ(d)μ(Tp))(i=1nTφ(iT))(j=1mTφ(jT))设 T=dp\begin{aligned} &\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(ij)\\ &=\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{\varphi(i)\varphi(j)\gcd(i,j)}{\varphi(\gcd(i,j))}\\ &=\sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(i)\varphi(j)[gcd(i,j)=d]\\ &=\sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\varphi(id)\varphi(jd)[gcd(i,j)=1]\\ &= \sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\varphi(id)[p|i]\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\varphi(jd)[p|j]\\ &=\sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{kd}\rfloor}\varphi(ikd)\sum_{j=1}^{\lfloor\frac{m}{kd}\rfloor}\varphi(jkd)\\ &=\sum_{T=1}^{n}\left(\sum_{d|T}\frac{d}{\varphi(d)}\mu(\frac{T}{p})\right)\left(\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\varphi(iT)\right)\left(\sum_{j=1}^{\lfloor\frac{m}{T}\rfloor}\varphi(jT)\right)& 设 \ T=dp \\ \end{aligned}\\

f(n)=dndφ(d)μ(np)f(n)=\sum\limits_{d|n}\frac{d}{\varphi(d)}\mu(\frac{n}{p}),线性筛预处理即可,O(nlnn)\mathcal{O}(n \ln n)

g(k,n)=i=1nφ(i,k)g(k,n)=\sum\limits_{i=1}^{n}\varphi(i,k),显然 g(k,n)=g(k,n1)+φ(nk)g(k,n)=g(k,n-1)+\varphi(nk)

则原式等于:

T=1nf(T)×g(T,nT)×g(T,mT)\begin{aligned} \sum_{T=1}^{n}f(T)\times g(T,\lfloor\frac{n}{T}\rfloor)\times g(T,\lfloor\frac{m}{T}\rfloor) \end{aligned}

发现整除分块不了,考虑把整个式子设出来:

h(a,b,n)=t=1nf(t)×g(t,a)×g(t,b)h(a,b,n)=\sum_{t=1}^{n}f(t)\times g(t,a) \times g(t,b)

容易发现,这其实就是一个差分:

h(a,b,n)=nl=nrandml=mrh(nr,mr,r)h(nr,mr,l)h(a,b,n)=\sum_{\lfloor\frac{n}{l}\rfloor=\lfloor\frac{n}{r}\rfloor \operatorname{and} \lfloor\frac{m}{l}\rfloor=\lfloor\frac{m}{r}\rfloor}h(\lfloor\frac{n}{r}\rfloor,\lfloor\frac{m}{r}\rfloor,r)-h(\lfloor\frac{n}{r}\rfloor,\lfloor\frac{m}{r}\rfloor,l)

再考虑根号分治,我们设一个阈值 SS,将所有 h(1,1,1)h(S,S,n)h(1,1,1) \sim h(S,S,n)hh 值预处理出来。

预处理式子就是:

h(j,k,i)=h(j,k,i1)+f(i)×g(i,j)×g(i,k)h(j,k,i)=h(j,k,i-1)+f(i)\times g(i,j)\times g(i,k)

对于 nrS\lfloor\frac{n}{r}\rfloor \leq S 可直接查询。

否则,可知 rnSr \leq \lfloor\frac{n}{S}\rfloor,数论分块计算即可。

#include <bits/stdc++.h>

using namespace std;

const int mod = 998244353;

const int S = 50;

const int maxn = 1e5;

bool vis[maxn + 7];

int tot, prime[maxn + 7];

int mu[maxn + 7], phi[maxn + 7], invphi[maxn + 7];

int sum[maxn + 7];

int *g[maxn + 7], *t[100][100];

int qpow(int x, int y)
{
    int res = 1;
    while (y)
    {
        if (y & 1)
            res = res * (long long)x % mod;
        x = x * (long long)x % mod;
        y >>= 1;
    }
    return res;
}

void init()
{
    phi[1] = mu[1] = invphi[1] = 1;
    for (int i = 2; i <= maxn; i++)
    {
        if (!vis[i])
            prime[++tot] = i, phi[i] = i + (mu[i] = -1);
        for (int j = 1; j <= tot && i * prime[j] <= maxn; j++)
        {
            vis[i * prime[j]] = true;
            if (i % prime[j] == 0)
            {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            mu[i * prime[j]] = -mu[i];
        }
        invphi[i] = qpow(phi[i], mod - 2);
    }
    for (int pp = 1; pp <= maxn; pp++)
        for (int q = pp, d = 1; q <= maxn; q += pp, d++)
            sum[q] = (sum[q] + pp * (long long)invphi[pp] % mod * mu[d]) % mod, sum[q] += (sum[q] < 0 ? mod : 0);
    for (int i = 1; i <= maxn; i++)
    {
        g[i] = new int[(maxn / i) + 1], g[i][0] = 0;
        for (int j = 1, sb = maxn / i; j <= sb; j++)
            g[i][j] = (g[i][j - 1] + phi[i * j]) % mod;
    }
    for (int j = 1; j <= S; j++)
        for (int k = j; k <= S; k++)
        {
            int len = maxn / max(j, k);
            t[j][k] = new int[len + 1], t[j][k][0] = 0;
            for (int i = 1; i <= len; i++)
                t[j][k][i] = (t[j][k][i - 1] + sum[i] * (long long)g[i][j] % mod * g[i][k] % mod) % mod;
        }
}

signed main()
{
	init();
    int T;
    scanf("%d", &T);
    while (T--)
    {
        int n, m, res = 0;
        scanf("%d%d", &n, &m);
        if (n > m)
            swap(n, m);
        for (int i = 1, kkk = m / S; i <= kkk; i++)
            res = (res + sum[i] * (long long)g[i][n / i] % mod * g[i][m / i] % mod) % mod;
        for (int i = m / S + 1, j; i <= n; i = j + 1)
        {
            j = min(n / (n / i), m / (m / i));
            res = (res + t[n / i][m / i][j] - t[n / i][m / i][i - 1]) % mod, res += (res < 0 ? mod : 0);
        }
        printf("%d\n", res);
    }
    return 0;
}
posted @   蒟蒻orz  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示