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} ight floor*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 }
原文地址:https://www.cnblogs.com/wfj2048/p/7492361.html