P2260 [清华集训2012]模积和

amodb=ab(a/b)

所以

i=1nj=1m(nmodi)×(mmodj)=i=1n(nmodi)j=1m(mmodj)i=1n(nmodi)(mmodj)

f(n,x)=i=1ni(x/i)

i=1n(nmodi)=i=1nni(n/i)=n2i=1ni(n/i)

so

=(n2f(n,n))(m2f(m,m))i=1n(nmodi)(mmodi)=(n2f(n,n))(m2f(m,m))i=1n(ni(n/i))(mi(m/i))

推导容斥的部分

i=1n(ni(n/i))(mi(m/i))=i=1n(ni(n/i))m(ni(n/i))i(m/i)=i=1nnmmi(n/i)ni(n/i)+i2(n/i)(m/i)=n2mmi=1ni(n/i)ni=1ni(m/i)+i=1ni2(n/i)(m/i)=n2mmf(n,n)nf(n,m)+i=1ni2(n/i)(m/i)

最后一个 还是可以除数分块 O(n) 求。

so 预处理 f(n,n),f(n,m),f(m,m) 和上面的东西,就做完了。

最终复杂度 O(n)

Code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const ll P=19940417;
inline ll read(){
	register ll x=0,f=0,ch=getchar();
	while('0'>ch||ch>'9')f^=ch=='-',ch=getchar();
	while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
	return f?-x:x;
}
inline ll sum0(ll l,ll r){
	return 1LL*(r-l+1)*(l+r)%P*9970209%P;
}
inline ll sum(ll x){
	x%=P;
	return (1LL*x*(x+1)%P*((x+x)%P+1)%P*3323403%P)%P;
}
inline ll solve(ll t,ll x){
	register ll res=0;
	for(register int l=1,r;l<=t;l=r+1){
		if(x/l==0)r=t;
		else r=min(x/(x/l),t);
		res+=1LL*sum0(l,r)*(x/l)%P;
		res%=P;
	}	
	return res%P;
}
ll a,b,c;
ll n,m,f1,f2,f3,f4,ans;
inline void solved(){
	for(register int l=1,r;l<=n;l=r+1){
		r=min(n/(n/l),m/(m/l));
		f4+=1LL*(sum(r)%P-sum(l-1)%P+P)%P*(n/l)%P*(m/l)%P;
		f4%=P;
	}
}
signed main(){
	n=read(),m=read();
	if(n>m)n^=m^=n^=m;
	f1=solve(n,n);
	f2=solve(n,m);
	f3=solve(m,m);
	solved();
	ans=1LL*(1LL*n*n%P-f1+P)%P*(1LL*m*m%P-f3+P)%P;
	ans-=1LL*(1LL*n*n%P*m%P-(1LL*m*f1%P)-(1LL*n*f2%P)+f4)%P;
	ans=(ans+P)%P;
	printf("%lld\n",ans);
	return 0;
}
posted @   jasony_sam  阅读(166)  评论(6编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示