P4240 毒瘤之神的考验

P4240 毒瘤之神的考验

求:

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

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

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

证明:
φ ( i ) φ ( j ) = i ∏ p ∣ i p − 1 p j ∏ p ∣ j p − 1 p p ∈ p r i m e s = i j ∏ p ∣ i j p − 1 p ∏ p ∣ gcd ⁡ ( i , j ) p − 1 p \begin{aligned} \varphi(i)\varphi(j)&=i\prod_{p|i}\frac{p-1}{p}j\prod_{p|j}\frac{p-1}{p} &p\in primes\\ &=ij\prod_{p|ij}\frac{p-1}{p}\prod_{p|\gcd(i,j)}\frac{p-1}{p} \end{aligned} φ(i)φ(j)=ipipp1jpjpp1=ijpijpp1pgcd(i,j)pp1pprimes
所以有:
φ ( i ) φ ( j ) gcd ⁡ ( i , j ) = i j ∏ p ∣ i j p − 1 p gcd ⁡ ( i , j ) ∏ p ∣ gcd ⁡ ( i , j ) p − 1 p = φ ( i j ) φ ( 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)φ(j)gcd(i,j)=ijpijpp1gcd(i,j)pgcd(i,j)pp1=φ(ij)φ(gcd(i,j))

化简式子,有:
∑ i = 1 n ∑ j = 1 m φ ( i j ) = ∑ i = 1 n ∑ j = 1 m φ ( i ) φ ( j ) gcd ⁡ ( i , j ) φ ( gcd ⁡ ( i , j ) ) = ∑ d = 1 n d φ ( d ) ∑ i = 1 n ∑ j = 1 m φ ( i ) φ ( j ) [ g c d ( i , j ) = d ] = ∑ d = 1 n d φ ( d ) ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ φ ( i d ) φ ( j d ) [ g c d ( i , j ) = 1 ] = ∑ d = 1 n d φ ( d ) ∑ p = 1 ⌊ n d ⌋ μ ( p ) ∑ i = 1 ⌊ n d ⌋ φ ( i d ) [ p ∣ i ] ∑ j = 1 ⌊ m d ⌋ φ ( j d ) [ p ∣ j ] = ∑ d = 1 n d φ ( d ) ∑ p = 1 ⌊ n d ⌋ μ ( p ) ∑ i = 1 ⌊ n k d ⌋ φ ( i k d ) ∑ j = 1 ⌊ m k d ⌋ φ ( j k d ) = ∑ T = 1 n ( ∑ d ∣ T d φ ( d ) μ ( T p ) ) ( ∑ i = 1 ⌊ n T ⌋ φ ( i T ) ) ( ∑ j = 1 ⌊ m T ⌋ φ ( j T ) ) 设   T = d p \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}\\ i=1nj=1mφ(ij)=i=1nj=1mφ(gcd(i,j))φ(i)φ(j)gcd(i,j)=d=1nφ(d)di=1nj=1mφ(i)φ(j)[gcd(i,j)=d]=d=1nφ(d)di=1dnj=1dmφ(id)φ(jd)[gcd(i,j)=1]=d=1nφ(d)dp=1dnμ(p)i=1dnφ(id)[pi]j=1dmφ(jd)[pj]=d=1nφ(d)dp=1dnμ(p)i=1kdnφ(ikd)j=1kdmφ(jkd)=T=1ndTφ(d)dμ(pT)i=1Tnφ(iT)j=1Tmφ(jT) T=dp
f ( n ) = ∑ d ∣ n d φ ( d ) μ ( n p ) f(n)=\sum\limits_{d|n}\frac{d}{\varphi(d)}\mu(\frac{n}{p}) f(n)=dnφ(d)dμ(pn),线性筛预处理即可, O ( n ln ⁡ n ) \mathcal{O}(n \ln n) O(nlnn)

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

则原式等于:
∑ T = 1 n f ( T ) × g ( T , ⌊ n T ⌋ ) × g ( T , ⌊ m T ⌋ ) \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} T=1nf(T)×g(T,Tn)×g(T,Tm)
发现整除分块不了,考虑把整个式子设出来:
h ( a , b , n ) = ∑ t = 1 n f ( 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)=t=1nf(t)×g(t,a)×g(t,b)
容易发现,这其实就是一个差分:
h ( a , b , n ) = ∑ ⌊ n l ⌋ = ⌊ n r ⌋ and ⁡ ⌊ m l ⌋ = ⌊ m r ⌋ h ( ⌊ n r ⌋ , ⌊ m r ⌋ , r ) − h ( ⌊ n r ⌋ , ⌊ m r ⌋ , 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) h(a,b,n)=ln=rnandlm=rmh(rn,rm,r)h(rn,rm,l)
再考虑根号分治,我们设一个阈值 S S S,将所有 h ( 1 , 1 , 1 ) ∼ h ( S , S , n ) h(1,1,1) \sim h(S,S,n) h(1,1,1)h(S,S,n) h h h 值预处理出来。

预处理式子就是:
h ( j , k , i ) = h ( j , k , i − 1 ) + 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) h(j,k,i)=h(j,k,i1)+f(i)×g(i,j)×g(i,k)
对于 ⌊ n r ⌋ ≤ S \lfloor\frac{n}{r}\rfloor \leq S rnS 可直接查询。

否则,可知 r ≤ ⌊ n S ⌋ r \leq \lfloor\frac{n}{S}\rfloor rSn,数论分块计算即可。

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值