luoguP2260 [清华集训2012]模积和

题意

\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}n\%i*m\%j*[i!=j]\)
\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}n\%i*m\%j-\sum\limits_{i=1}^{min(n,m)}n\%i*m\%i\)
\(\sum\limits_{i=1}^n(n-\lfloor\frac{n}{i}\rfloor*i)\sum\limits_{j=1}^m(m-\lfloor\frac{m}{j}\rfloor*j)-\sum\limits_{i=1}^{min(n,m)}n*m-(n*\lfloor\frac{m}{i}\rfloor+m*\lfloor\frac{n}{i}\rfloor)*i+\lfloor\frac{n}{i}\rfloor*\lfloor\frac{m}{i}\rfloor*i^2\)
除法分块就好了。

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int mod=19940417;
const int inv6=3323403;
const int inf=1e9;
int n,m,ans;
inline int calc1(int l,int r){return ((l+r)*(r-l+1)/2)%mod;}
inline int calc2(int x){return x*(x+1)%mod*(2*x+1)%mod*inv6%mod;}
inline int calc(int x)
{
	int res=0;
	for(int l=1,r;l<=x;l=r+1)
	{
		r=x/(x/l);
		int tmp=x*(r-l+1)%mod-(x/l)*calc1(l,r)%mod;
		res=((res+tmp)%mod+mod)%mod;
	}
	return res;
}
signed main()
{
	scanf("%lld%lld",&n,&m);
	if(n>m)swap(n,m);
	ans=calc(n)*calc(m)%mod;
	for(int l=1,r;l<=n;l=r+1)
	{
		r=min(n/(n/l),m/(m/l));
		int tmp1,tmp2,tmp3;
		tmp1=n*m%mod*(r-l+1)%mod;
		tmp2=(n*(m/l)%mod+m*(n/l)%mod)%mod*calc1(l,r)%mod;
		tmp3=(n/l)*(m/l)%mod*((calc2(r)-calc2(l-1))%mod+mod)%mod;
		ans=((ans-tmp1+tmp2-tmp3)%mod+mod)%mod;
	}
	printf("%lld",ans);
	return 0;
}
posted @ 2019-11-29 09:09  nofind  阅读(85)  评论(0编辑  收藏  举报