bzoj 4174 tty的求助 数论 莫比乌斯反演

来源:互联网 发布:量化交易 不会编程 编辑:程序博客网 时间:2024/05/16 15:31

题意:求Nn=1Mm=1m1k=0nk+xm

先膜PoPoQQQ大爷。

Nn=1Mm=1m1k=0nk+xm

=Nn=1Mm=1m1k=0nk%m+xm+nkmnk%mm

然后先不考虑n,m,分三部分算。
gcd(n,m)=d

m1k=0nk%m+xm
=m1k=0d(ndk%md)+xm
然后因为ndmd 互质,所以:
=dmd1k=0dk+xm
=dmd1k=0(dk+x%mm+xx%mm)
然后因为dkx%m 都小于m,所以dk+x%m 只能是1或0:
=dmd1k=0([dk+x%mm]+xx%mm)
=dx%md+dmdxx%mm
=dxd

m1k=0nkm=nm(m1)m2=n(m1)2

m1k=0nk%mm=dmd1k=0dkm=md2

然后加到一起,不含d的项O(1) 算,枚举d,反演一下,然后O(nlogn) 就可以算出来了。

#include <bits/stdc++.h>using namespace std;#define N 510000#define mod 998244353#define ll long longint n,m;double x;int mu[N],prime[N],ip[N],cnt,ans;void liner_shuffle(){    mu[1]=1;    for(int i=2;i<=n;i++)    {        if(!ip[i])prime[++cnt]=i,mu[i]=-1;        for(int j=1;j<=cnt&&i*prime[j]<=n;j++)        {            ip[i*prime[j]]=1;            mu[i*prime[j]]=-mu[i];            if(i%prime[j]==0)            {                mu[i*prime[j]]=0;                break;            }        }    }}int S(int x){return (ll)x*(x+1)/2%mod;}int qpow(int x,int y){    int ret=1;    while(y)    {        if(y&1)ret=(ll)ret*x%mod;        x=(ll)x*x%mod;y>>=1;    }    return ret;}int main(){    scanf("%d%d%lf",&n,&m,&x);    liner_shuffle();    ans=((ll)S(n)*S(m)%mod-(ll)S(n)*m%mod-(ll)S(m)*n%mod)%mod;    for(int i=1;i<=n&&i<=m;i++)    {        int t=(i+(ll)2*i*(ll)(x/i))%mod,sum=0;        for(int j=i,k=1;j<=n&&j<=m;j+=i,k++)            sum=(sum+(ll)mu[k]*(n/j)%mod*(m/j)%mod)%mod;        ans=(ans+(ll)t*sum%mod)%mod;    }    ans=(ans+mod)%mod;    ans=(ll)ans*qpow(2,mod-2)%mod;    printf("%d\n",ans);    return 0;}   
0 0
原创粉丝点击