首页 > 代码库 > 【BZOJ2956】模积和 分块
【BZOJ2956】模积和 分块
【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。
样例说明
答案为(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。
题解:
推到这之后发现有个i²不好搞,但是我们有平方和定理
然后分块就好了
脏脏的从黄学长的博客和百度上扒了图片,又直接扒了6的乘法逆元,不要打我~
#include <cstdio>#include <cstring>#include <iostream>#define mod 19940417ll#define m6 3323403ll//6的逆元using namespace std;typedef long long ll;ll n,m,i,last,ans;ll s1,s2,s3;ll pm(ll x,ll y){ ll z=1; while(y) { if(y&1) z=(z*x)%mod; x=(x*x)%mod,y>>=1; } return z;}ll sum(ll x){ return x*(x+1)%mod*(2*x+1)%mod*m6%mod;}int main(){ scanf("%lld%lld",&n,&m); if(n>m) swap(n,m); for(i=1;i<=n;i=last+1) { last=n/(n/i); s1+=((last-i+1)*n-(i+last)*(last-i+1)/2%mod*(n/i)%mod+mod)%mod; s1%=mod; } for(i=1;i<=m;i=last+1) { last=m/(m/i); s2+=((last-i+1)*m-(i+last)*(last-i+1)/2%mod*(m/i)%mod+mod)%mod; s2%=mod; } for(i=1;i<=n;i=last+1) { last=min(n/(n/i),m/(m/i)); s3+=(last-i+1)*n%mod*m%mod; s3-=(i+last)*(last-i+1)/2%mod*((n/i)*m%mod+(m/i)*n%mod)%mod; s3+=(n/i)*(m/i)%mod*(sum(last)-sum(i-1)+mod)%mod; s3%=mod; } ans=(s1*s2%mod-s3+mod)%mod; printf("%lld",ans); return 0;}
【BZOJ2956】模积和 分块
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。