HDU6588 经典gcd求和

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Feynman1999/article/details/100024190

需要求

i=1ngcd(i3,i)mod  998244353n=1021 \sum_{i=1}^n\gcd(\lfloor{\sqrt[3]{i}}\rfloor,i)\mod 998244353 \quad n = 10^{21}

思路

m=n31m=\lfloor \sqrt[3]{n} \rfloor-1

i=1ngcd(floor(i3),i)=i=1mj=i3(i+1)31gcd(i,j)+i=(m+1)3ngcd(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)

考虑一个函数(前缀和,差分后即为上面部分所求,这个想法也比较自然),f(n)=i=1ngcd(m,i)f(n) = \sum_{i=1}^ngcd(m,i)
f(n)=i=1ngcd(m,i)=i=1ndgcd(m,i)ϕ(d)=dmϕ(d)nd 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
则 :
注意下面的,m=n31m=\lfloor \sqrt[3]{n} \rfloor-1
i=1ngcd(floor(i3),i)=i=1mj=i3(i+1)31gcd(i,j)+i=(m+1)3ngcd(m+1,i)=i=1mdiϕ(d)[(i+1)31di31d]+dm+1ϕ(d)[nd(m+1)31d]=d=1mϕ(d)i=1m/d[(id+1)31d(id)31d]+dm+1ϕ(d)[nd(m+1)31d]=d=1mϕ(d)i=1m/d[3di2+3i+1()]+dm+1ϕ(d)[nd(m+1)31d] \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 ]
因此可以计算 ,时间复杂度O(1e7+T(1e7+1e7)O(1e7 + T*(1e7+\sqrt{1e7}) 其中TT为数据组数,最左边的1e71e7为预处理欧拉函数的时间。

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

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;
}


文章创建于: 2019-08-22 21:03:21
展开阅读全文

没有更多推荐了,返回首页