bzoj 2956: 模积和

2019-04-13 17:02发布

题意:求nimj(n mod i)(m mod j)(i!=j)

题解:

我各种sb错误荒废了一上午啊啊啊。
先无视限制:即ni(n mod i)mj(m mod j)
同bzoj 1257(题解
然后要减去相等的情况。
min(n,m)i(n mod i)(m mod i)
=min(n,m)i(nnii)(mmii)
=min(n,m)i(nm)(nim+min)+nimii2
然后就能分块了。

注意:乘一步mod一步啊啊啊!!!

code: #include #include #include #include #define LL long long using namespace std; const LL mod=19940417,inv=3323403; LL sum(LL l,LL r){return ((LL)(r-l+1)*(LL)(l+r)/2)%mod;} LL sum_2(LL n){return (LL)n*(LL)(n+1)%mod*(LL)(2*n+1)%mod*inv%mod;} LL solve(LL n) { LL ans=0;LL pos; for(LL i=1;i<=n;i=pos+1) { pos=(n/(n/i)); ans=(ans+((LL)n*(pos-i+1)-(LL)(n/i)*sum(i,pos))%mod)%mod; } return ans; } LL solve2(LL n,LL m) { if(n>m) swap(n,m); LL ans=0;LL pos; for(LL i=1;i<=n;i=pos+1) { pos=min(n/(n/i),m/(m/i)); LL t1=n*m%mod*(pos-i+1)%mod,t2=sum(i,pos)%mod*(n*(m/i)%mod+m*(n/i)%mod)%mod,t3=(m/i)*(n/i)%mod*(sum_2(pos)-sum_2(i-1)+mod)%mod; t3=(t3+mod)%mod; ans=((ans+(t1-t2+t3)%mod)+mod)%mod; } return ans; } LL n,m; int main() { scanf("%lld %lld",&n,&m); printf("%lld",((solve(n)*solve(m)%mod-solve2(n,m))%mod+mod)%mod); }