1. 程式人生 > >bzoj2956 模積和

bzoj2956 模積和

div stdin tput c++ for 一個 註意 暴力 mes

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 }

bzoj2956 模積和