HDU 6588 Function 题解

题意:给定 n n n,求 ∑ i = 1 n gcd ⁡ ( ⌊ i 3 ⌋ , i )   m o d   998244353 \displaystyle \sum_{i=1}^n \gcd\left( \left\lfloor\sqrt[3]{i}\right\rfloor,i\right) \bmod 998244353 i=1ngcd(3i ,i)mod998244353,其中 n ≤ 1 × 1 0 21 n \leq 1\times 10^{21} n1×1021

首先考虑分块,根据 i 3 \sqrt[3]{i} 3i 的值可以将 [ 1 , n ] [1,n] [1,n] 的整数分成 n 3 \sqrt[3]{n} 3n 块。记 m = ⌊ n 3 ⌋ m=\left \lfloor \sqrt[3]{n} \right \rfloor m=3n ,原式可化为 ( ∑ i = 1 m ∑ j = i 3 ( i + 1 ) 3 − 1 gcd ⁡ ( i , j ) ) + ∑ i = m 3 n gcd ⁡ ( m , i ) \displaystyle \left (\sum_{i=1}^m \sum_{j=i^3}^{(i+1)^3-1}\gcd(i,j) \right )+\sum_{i=m^3}^n \gcd(m,i) i=1mj=i3(i+1)31gcd(i,j)+i=m3ngcd(m,i)。首先来考虑固定 i i i,整块的做法。

首先容易注意到, gcd ⁡ ( i , j ) = gcd ⁡ ( j , i   m o d   j ) \gcd(i,j)=\gcd(j,i \bmod j) gcd(i,j)=gcd(j,imodj),因而对于一个固定的 d d d ∑ i = d 3 d 3 + 3 d 2 + 3 d gcd ⁡ ( d , i ) = ∑ i = d 3 d 3 + 3 d 2 + 3 d gcd ⁡ ( d , i   m o d   d ) \displaystyle \sum_{i=d^3}^{d^3+3d^2+3d} \gcd(d,i)=\sum_{i=d^3}^{d^3+3d^2+3d}\gcd(d,i \bmod d) i=d3d3+3d2+3dgcd(d,i)=i=d3d3+3d2+3dgcd(d,imodd)。而集合 [ d 3 , d 3 + 3 d 2 + 3 d ] [d^3,d^3+3d^2+3d] [d3,d3+3d2+3d] 可以拆分为 3 d 2 + 1 3d^2+1 3d2+1 个完整的 ∑ i = 1 d gcd ⁡ ( i , d ) \displaystyle \sum_{i=1}^d \gcd(i,d) i=1dgcd(i,d) 和最后的一项 gcd ⁡ ( d , d 3 + 3 d 2 + 3 d ) = d \gcd(d,d^3+3d^2+3d)=d gcd(d,d3+3d2+3d)=d,因而原式前半部分可化为:
∑ d = 1 m ∑ i = d 3 d 3 + 3 d 2 + 3 d gcd ⁡ ( i , d ) = ∑ d = 1 m ( ( 3 d + 1 ) ∑ i = 1 d gcd ⁡ ( d , i ) ) + d \sum_{d=1}^{m}\sum_{i=d^3}^{d^3+3d^2+3d} \gcd(i,d)=\sum_{d=1}^{m} \left((3d+1)\sum_{i=1}^d \gcd(d,i)\right)+d d=1mi=d3d3+3d2+3dgcd(i,d)=d=1m((3d+1)i=1dgcd(d,i))+d
对于最后一部分,式子也是形如 ∑ i = m 3 n gcd ⁡ ( m , i ) \displaystyle \sum_{i=m^3}^n \gcd(m,i) i=m3ngcd(m,i),考虑 ∑ i = 1 n gcd ⁡ ( i , a ) \displaystyle \sum_{i=1}^n \gcd(i,a) i=1ngcd(i,a) 的求法。
∑ i = 1 n gcd ⁡ ( i , a ) = ∑ d ∣ a d ∑ i = 1 n [ gcd ⁡ ( i , a ) = d ] = ∑ d ∣ a d ∑ i = 1 ⌊ n d ⌋ ∑ e d ∣ ( d i ) , e ∣ a d μ ( e ) = t = e d ∑ d ∣ a d ∑ i = 1 ⌊ n d ⌋ ∑ t ∣ d i , t ∣ a μ ( t d ) = ∑ t ∣ a ⌊ n t ⌋ ∑ d ∣ t d μ ( t d ) = ∑ t ∣ a ⌊ n t ⌋ φ ( t ) \begin{aligned} \sum_{i=1}^n \gcd(i,a)=&\sum_{d|a} d\sum_{i=1}^n[\gcd(i,a)=d]\\ =&\sum_{d|a}d\sum_{i=1}^{\lfloor{\frac{n}{d}} \rfloor} \sum_{ed|(di),e|\frac{a}{d}} \mu(e)\\ \overset{\underset{t=ed}{}}=&\sum_{d|a}d\sum_{i=1}^{\lfloor{\frac{n}{d}} \rfloor} \sum_{t|di,t|a} \mu \left(\dfrac{t}{d}\right)\\ =&\sum_{t|a} \left\lfloor\frac{n}{t}\right \rfloor\sum_{d|t} d\mu\left(\dfrac{t}{d}\right)\\ =&\sum_{t|a} \left \lfloor\dfrac{n}{t} \right \rfloor\varphi(t) \end{aligned} i=1ngcd(i,a)===t=ed==dadi=1n[gcd(i,a)=d]dadi=1dned(di),edaμ(e)dadi=1dntdi,taμ(dt)tatndtdμ(dt)tatnφ(t)
a ≠ n a \neq n a=n,对于单个的 a a a 可以考虑在 O ( a ) \mathcal{O}(\sqrt{a}) O(a ) 的时间内枚举因子求得。对于大部分的情况—— a = n a=n a=n,原式可化简为 ∑ t ∣ n n t φ ( t ) = φ ∗ i d \displaystyle \sum_{t|n} \dfrac{n}{t} \varphi(t)=\varphi*id tntnφ(t)=φid,因而是一个积性函数,不妨设为 f ( n ) f(n) f(n),考虑欧拉筛线性的求得。

欧拉筛的难点在于 f ( p k ) → f ( p k + 1 ) f(p^k) \to f(p^{k+1}) f(pk)f(pk+1) 的转化。
f ( p k ) = ∑ t ∣ p k p k t φ ( t ) = ∑ i = 0 k p k − i φ ( p i ) = p k + ∑ i = 1 k p k − i p i − 1 ( p − 1 ) = p + ( p − 1 ) ∑ i = 1 k p k − 1 = p + ( p − 1 ) k p k − 1 = p ( f ( p k − 1 ) + φ ( p k − 1 ) ) \begin{aligned} f(p^k)=\sum_{t|p^k} \dfrac{p^k}{t} \varphi(t)=&\sum_{i=0}^k p^{k-i} \varphi(p^i)\\ =&p^k+\sum_{i=1}^k p^{k-i} p^{i-1}(p-1)\\ =&p+(p-1)\sum_{i=1}^k p^{k-1}\\ =&p+(p-1)kp^{k-1}\\ =&p(f(p^{k-1})+\varphi(p^{k-1})) \end{aligned} f(pk)=tpktpkφ(t)=====i=0kpkiφ(pi)pk+i=1kpkipi1(p1)p+(p1)i=1kpk1p+(p1)kpk1p(f(pk1)+φ(pk1))

因而维护一个 φ \varphi φ 数组,最小质因子 M \mathcal M M,在该数中最小质因子 T \mathcal T T 的次方数(例如, T 12 = 2 2 = 4 {\mathcal T}_{12}=2^2=4 T12=22=4)即可。对于 p ∤ n p \nmid n pn,则 f ( n p ) = f ( n ) f ( p ) = f ( n ) ( 2 p − 1 ) f(np)=f(n)f(p)=f(n)(2p-1) f(np)=f(n)f(p)=f(n)(2p1);若 p ∣ n p|n pn,考虑 T n = p i {\mathcal T}_n=p^i Tn=pi
f ( n p ) = f ( n p i × p i + 1 ) = f ( n p i ) f ( p i + 1 ) = f ( n p i ) × p ( f ( p i ) + φ ( p i ) ) ) = p [ f ( n ) + f ( n p i ) φ ( p i ) ] \begin{aligned} f(np)=&f\left(\dfrac{n}{p^i} \times p^{i+1}\right)\\ =&f\left(\dfrac{n}{p^i}\right)f(p^{i+1})\\ =&f\left(\dfrac{n}{p^i}\right)\times p(f(p^i)+\varphi(p^i)))\\ =&p\left[f(n)+f\left(\dfrac{n}{p^i}\right) \varphi(p^i)\right] \end{aligned} f(np)====f(pin×pi+1)f(pin)f(pi+1)f(pin)×p(f(pi)+φ(pi)))p[f(n)+f(pin)φ(pi)]
因而同步的转移即可。

#include <bits/stdc++.h>
using namespace std;
const long long mod = 998244353;
const int N = 10000000;
char a[30];
int sum[N + 5];
int f[N + 5], prime[N + 5], phi[N + 5], minfac[N + 5], mintimes[N + 5];
int tot;
long long power(long long a, long long x)
{
    long long ans = 1;
    while(x)
    {
        if (x & 1)
            ans = ans * a % mod;
        a = a % a % mod;
        x >>= 1;
    }
    return ans;
}
long long inv(long long a)
{
    return power(a, mod - 2);
}
inline void sieve(int n)
{
    phi[1] = f[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if(!minfac[i])
        {
            minfac[i] = prime[++tot] = mintimes[i] = i;
            phi[i] = i - 1;
            f[i] = i + i - 1;
        }
        for (int j = 1; j <= tot && (long long)prime[j] * i <= n; j++)
        {
            long long num = prime[j] * i;
            if (i % prime[j])
            {
                minfac[num] = mintimes[num] = prime[j];
                phi[num] = (long long)phi[i] * (prime[j] - 1);
                f[num] = (long long)f[i] * (2 * prime[j] - 1) % mod;
            }
            else
            {
                minfac[num] = prime[j];
                mintimes[num] = (long long)prime[j] * mintimes[i];
                phi[num] = (long long)phi[i] * prime[j];
                f[num] = (f[i] + (long long)f[i / mintimes[i]] * phi[mintimes[i]] % mod) % mod * (long long)prime[j] % mod;
            }
        }
    }
    for (int i = 1; i <= n; i++)
        sum[i] = ((3ll * i + 3) * f[i] % mod + i + sum[i - 1]) % mod;
}
long long g(long long n, long long m)
{
    long long ans = 0;
    for (int i = 1; i * i <= m;i++)
        if (m % i == 0)
        {
            int j = m / i;
            ans = (ans + phi[i] * (n / i) % mod) % mod;
            if (i != j)
                ans = (ans + phi[j] * (n / j) % mod) % mod;
        }
    return ans;
}
int main()
{
    sieve(N);
    int t;
    scanf("%d", &t);
    while(t--)
    {
        __int128_t n = 0;
        scanf("%s", a);
        int len = strlen(a);
        for (int i = 0; i < len;i++)
            n = n * 10 + a[i] - 48;
        __int128_t left = 0, right = N, lim = 0;
        while (left <= right)
        {
            __int128_t mid = (left + right) >> 1;
            if (mid * mid * mid <= n)
            {
                lim = mid;
                left = mid + 1;
            }
            else
                right = mid - 1;
        }
        long long ans = (((n / lim - lim * lim) % mod * f[lim] % mod + lim) % mod + g(n % lim, lim)) % mod;
        ans = (ans + sum[lim - 1]) % mod;
        printf("%lld\n", ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值