HDU6588 经典gcd求和

需要求

∑ i = 1 n gcd ⁡ ( ⌊ i 3 ⌋ , i ) m o d    998244353 n = 1 0 21 \sum_{i=1}^n\gcd(\lfloor{\sqrt[3]{i}}\rfloor,i)\mod 998244353 \quad n = 10^{21} i=1ngcd(3i ,i)mod998244353n=1021

思路

m = ⌊ n 3 ⌋ − 1 m=\lfloor \sqrt[3]{n} \rfloor-1 m=3n 1

∑ i = 1 n g c d ( f l o o r ( i 3 ) , i ) = ∑ i = 1 m ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) + ∑ i = ( m + 1 ) 3 n g c d ( m + 1 , i ) \sum_{i=1}^{n}gcd(floor(\sqrt[3]{i}),i) = \sum_{i=1}^{m}\sum\limits_{j=i^{3}}^{(i+1)^{3}-1}gcd(i,j) \quad + \quad \sum\limits_{i=(m+1)^{3}}^{n}gcd(m+1,i) i=1ngcd(floor(3i ),i)=i=1mj=i3(i+1)31gcd(i,j)+i=(m+1)3ngcd(m+1,i)

考虑一个函数(前缀和,差分后即为上面部分所求,这个想法也比较自然), f ( n ) = ∑ i = 1 n g c d ( m , i ) f(n) = \sum_{i=1}^ngcd(m,i) f(n)=i=1ngcd(m,i)
f ( n ) = ∑ i = 1 n g c d ( m , i ) = ∑ i = 1 n ∑ d ∣ g c d ( m , i ) ϕ ( d ) = ∑ d ∣ m ϕ ( d ) ∗ ⌊ n d ⌋ f(n) = \sum_{i=1}^ngcd(m,i) \\ = \sum_{i=1}^n \sum_{d|gcd(m,i)}\phi(d) \\ = \sum_{d|m} \phi(d)*\left \lfloor \frac{n}{d} \right \rfloor f(n)=i=1ngcd(m,i)=i=1ndgcd(m,i)ϕ(d)=dmϕ(d)dn
则 :
注意下面的, m = ⌊ n 3 ⌋ − 1 m=\lfloor \sqrt[3]{n} \rfloor-1 m=3n 1
∑ i = 1 n g c d ( f l o o r ( i 3 ) , i ) = ∑ i = 1 m ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) + ∑ i = ( m + 1 ) 3 n g c d ( m + 1 , i ) = ∑ i = 1 m ∑ d ∣ i ϕ ( d ) ∗ [ ⌊ ( i + 1 ) 3 − 1 d ⌋ − ⌊ i 3 − 1 d ⌋ ] + ∑ d ∣ m + 1 ϕ ( d ) ∗ [ ⌊ n d ⌋ − ⌊ ( m + 1 ) 3 − 1 d ⌋ ] = ∑ d = 1 m ϕ ( d ) ∗ ∑ i = 1 ⌊ m / d ⌋ [ ⌊ ( i d + 1 ) 3 − 1 d ⌋ − ⌊ ( i d ) 3 − 1 d ⌋ ] + ∑ d ∣ m + 1 ϕ ( d ) ∗ [ ⌊ n d ⌋ − ⌊ ( m + 1 ) 3 − 1 d ⌋ ] = ∑ d = 1 m ϕ ( d ) ∗ ∑ i = 1 ⌊ m / d ⌋ [ 3 d i 2 + 3 i + 1 ( 注 意 这 里 是 下 取 整 ) ] + ∑ d ∣ m + 1 ϕ ( d ) ∗ [ ⌊ n d ⌋ − ⌊ ( m + 1 ) 3 − 1 d ⌋ ] \sum_{i=1}^{n}gcd(floor(\sqrt[3]{i}),i) = \sum_{i=1}^{m}\sum\limits_{j=i^{3}}^{(i+1)^{3}-1}gcd(i,j) \quad + \quad \sum\limits_{i=(m+1)^{3}}^{n}gcd(m+1,i) \\ = \sum_{i=1}^{m}\sum_{d|i}\phi(d)*\left [ \left \lfloor \frac{(i+1)^3 -1}{d} \right \rfloor - \left \lfloor \frac{i^3-1}{d} \right \rfloor \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] \\ = \sum_{d=1}^{m}\phi(d)*\sum_{i=1}^{ \lfloor m/d \rfloor}\left [ \left \lfloor \frac{(id+1)^3 -1}{d} \right \rfloor - \left \lfloor \frac{(id)^3-1}{d} \right \rfloor \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] \\ = \sum_{d=1}^{m}\phi(d)*\sum_{i=1}^{ \lfloor m/d \rfloor}\left [ 3di^2 + 3i + 1(注意这里是下取整) \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] i=1ngcd(floor(3i ),i)=i=1mj=i3(i+1)31gcd(i,j)+i=(m+1)3ngcd(m+1,i)=i=1mdiϕ(d)[d(i+1)31di31]+dm+1ϕ(d)[dnd(m+1)31]=d=1mϕ(d)i=1m/d[d(id+1)31d(id)31]+dm+1ϕ(d)[dnd(m+1)31]=d=1mϕ(d)i=1m/d[3di2+3i+1()]+dm+1ϕ(d)[dnd(m+1)31]
因此可以计算 ,时间复杂度 O ( 1 e 7 + T ∗ ( 1 e 7 + 1 e 7 ) O(1e7 + T*(1e7+\sqrt{1e7}) O(1e7+T(1e7+1e7 ) 其中 T T T为数据组数,最左边的 1 e 7 1e7 1e7为预处理欧拉函数的时间。

本题的关键在于推导的倒数第二行变换贡献,从枚举 i i i变为枚举 d d d,使得复杂度降了下来

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;
const int mod = 998244353;
const int inv2 = 499122177;
const int inv6 = 166374059;
const int maxn=1e7+10;
template <class T>
void read(T &x) {
	static char ch;static bool neg;
	for(ch=neg=0;ch<'0' || '9'<ch;neg|=ch=='-',ch=getchar());
	for(x=0;'0'<=ch && ch<='9';(x*=10)+=ch-'0',ch=getchar());
	x=neg?-x:x;
}
lll n;
int tot;
bool valid[maxn];//is prime or not
int phi[maxn];// phi
int ans[maxn];// prime
void getprime(int n)
{
    tot=0;
    phi[1]=1;
    memset(valid,true,sizeof(valid));
    for(int i=2;i<=n;++i){
        if(valid[i]){
            tot++;
            ans[tot]=i;
            phi[i]=i-1;//i为素数
        }
        //下面的主角是小于等于i的每个质数
        for(int j=1;(j<=tot) && (i*ans[j]<=n);++j){
            valid[i*ans[j]]=false;
            if(i%ans[j]==0){//ans[j]是i的素因子
                phi[i*ans[j]]=phi[i]*ans[j];
                break;//如果整除就break;
            }
            else phi[i*ans[j]]=phi[i]*(ans[j]-1);
        }
    }
}
lll pow3(lll x)
{
    return x*x*x;
}
//n(n+1)(2n+1)/6
ll solve(int d, ll m){
    ll up = m/d;
    ll ans1 = (1+up)*up%mod*inv2%mod;
    ll ans2 = d*up%mod*(up+1)%mod*(2*up+1)%mod*inv6%mod;
    return ((ans1+ans2)*3 + up)%mod;
}
int main()
{
    getprime(1e7);
    int t;
    cin>>t;
    while(t--)
    {
        read(n);
        int m = pow(n,1.0/3) - 1e5;
        for(;pow3(m)<=n;m++);
        m-=2;
        ll ans = 0;
        for(int d=1;d<=m;++d){
            ans=(ans + 1LL*phi[d]*solve(d,m)%mod)%mod;
        }
        ll res = 0;
        int now=m+1;
        for(int i=1;i*i<=now;++i){
            if(now%i==0){//i now/i
                res = (res + 1LL*phi[i]*((n/i-(pow3(m+1)-1)/i)%mod) )%mod;
                if(i*i!=now) res = (res + 1LL*phi[now/i]*((n/(now/i)-(pow3(m+1)-1)/(now/i))%mod) )%mod;
            }
        }
        ans = (ans + res)%mod;
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值