bzoj2956 模积和
Description
求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j<=m,i≠j。
Input
第一行两个数n,m。
Output
一个整数表示答案mod 19940417的值
Sample Input
3 4
Sample Output
1
样例说明
答案为(3 mod 1)*(4 mod 2)+(3 mod 1) * (4 mod 3)+(3 mod 1) * (4 mod 4) + (3 mod 2) * (4 mod 1) + (3 mod 2) * (4 mod 3) + (3 mod 2) * (4 mod 4) + (3 mod 3) * (4 mod 1) + (3 mod 3) * (4 mod 2) + (3 mod 3) * (4 mod 4) = 1
数据规模和约定
对于100%的数据n,m<=10^9。
正解:数论分块。
注意到$n \mod i=n-\left \lfloor \frac{n}{i} \right \rfloor*i$,然后我们容斥一下,先总体算出来,再减去不合法的情况。
把式子全部暴力展开,发现可以直接数论分块乱搞到$O(\sqrt{n})$,于是这题就做完了。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define phi (17091780) 6 #define rhl (19940417) 7 8 using namespace std; 9 10 ll s,n,m,inv,ans,ans1,ans2,ans3; 11 12 il ll qpow(RG ll a,RG ll b){ 13 RG ll ans=1; 14 while (b){ 15 if (b&1) ans=ans*a%rhl; 16 a=a*a%rhl,b>>=1; 17 } 18 return ans; 19 } 20 21 il ll calc(RG ll x){ return (1+x)*x/2%rhl; } 22 23 il ll cal(RG ll x){ return x*(x+1)%rhl*(2*x+1)%rhl*inv%rhl; } 24 25 int main(){ 26 #ifndef ONLINE_JUDGE 27 freopen("modsum.in","r",stdin); 28 freopen("modsum.out","w",stdout); 29 #endif 30 cin>>n>>m,inv=qpow(6,phi-1); 31 for (RG ll i=1,pos;i<=n;i=pos+1) 32 pos=n/(n/i),ans1=(ans1+n/i*(calc(pos)-calc(i-1)+rhl))%rhl; 33 for (RG ll i=1,pos;i<=m;i=pos+1) 34 pos=m/(m/i),ans2=(ans2+m/i*(calc(pos)-calc(i-1)+rhl))%rhl; 35 ans1=(1LL*n*n-ans1)%rhl,ans2=(1LL*m*m-ans2)%rhl,ans=1LL*ans1*ans2%rhl,s=min(n,m); 36 for (RG ll i=1,pos;i<=s;i=pos+1) 37 pos=min(n/(n/i),m/(m/i)),ans3=(ans3+n*m%rhl*(pos-i+1)%rhl-(n*(m/i)+m*(n/i))%rhl*(calc(pos)-calc(i-1)+rhl)%rhl+rhl+(n/i)*(m/i)%rhl*(cal(pos)-cal(i-1)+rhl)%rhl)%rhl; 38 ans=(ans-ans3+rhl)%rhl; cout<<ans; return 0; 39 }