题目大意:求
∑Nn=1∑Mm=1∑m?1k=0?nk+xm? mod 998244353
假设
n
和
m
都已经确定了,现在要求这坨玩应:
∑m?1k=0?nk+xm?
=∑m?1k=0(?nk%m+xm?+nk?nk%mm)
=∑m?1k=0(?nk%m+xm?+nkm?nk%mm)
我们一项一项考虑
令
d=gcd(n,m)
,那么有
∑m?1k=0?nk%m+xm?
=d?∑md?1k=0?kd+xm?
=d?(md?x?x%mm+∑md?1k=0?kd+x%mm?)
=d?(md?x?x%mm+∑md?1k=0[kd+x%m≥m])
=d?(x?x%md+?x%md?)
=d??xd?
∑m?1k=0nkm=nm?m?(m?1)2=n?m?n2
∑m?1k=0nk%mm=d?∑md?1k=0kdm=d2m?(md?1)?md2=m?d2
故答案为
∑Nn=1∑Mm=1(d??xd?+n?m?n2?m?d2)
=12?∑Nn=1∑Mm=1(2?d??xd?+d+n?m?n?m)
=12?(S(N)?S(M)?S(N)?m?S(M)?n+∑min(N,M)d=1(d+2?d??xd?)∑min(?Nd?,?Md?)k=1μ(k)??Nd?k???Md?k?)
其中
S(n)=n?(n+1)2
然后
O(nlogn)
枚举
d
和
k
即可
#include
#include
#include
#include
#define M 500500 #define MOD 998244353 using namespace std; int n,m,x; long long ans; int mu[M]; int prime[M],tot; bool not_prime[M]; void Linear_Shaker() { int i,j; mu[1]=1; for(i=2;i<=500000;i++) { if(!not_prime[i]) { prime[++tot]=i; mu[i]=MOD-1; } for(j=1;prime[j]*i<=500000;j++) { not_prime[prime[j]*i]=true; if(i%prime[j]==0) { mu[prime[j]*i]=0; break; } mu[prime[j]*i]=(MOD-mu[i])%MOD; } } } long long Sum(long long n) { return (n*(n+1)>>1)%MOD; } int main() { int i,j; cin>>n>>m>>x; Linear_Shaker(); ans=((Sum(n)*Sum(m)-Sum(n)*m-Sum(m)*n)%MOD+MOD)%MOD; if(n>m) swap(n,m); for(i=1;i<=n;i++) { long long temp=i+x/i*i*2; for(j=1;j*i<=n;j++) (ans+=temp*mu[j]%MOD*(n/i/j)%MOD*(m/i/j)%MOD)%=MOD; } cout<<(ans*(MOD+1>>1)%MOD)<
?