数论--P2260 [清华集训] 模积和

题目链接

在这里插入图片描述
喜闻乐见推柿子时间:
∑ i = 1 n ∑ j = 1 m ( n   %   i ) ( m   %   j )   ,   i ≠ j = ∑ i = 1 n ∑ j = 1 m ( n − ⌊ n i ⌋ i ) ( m − ⌊ m j ⌋ j ) − ∑ i = 1 m i n ( n , m ) ( n − ⌊ n i ⌋ i ) ( m − ⌊ m i ⌋ i ) = ∑ i = 1 n ( n − ⌊ n i ⌋ i ) ∑ j = 1 m ( m − ⌊ m j ⌋ j ) − ∑ i = 1 m i n ( n , m ) ( n m − n ⌊ m i ⌋ i − m ⌊ n i ⌋ i + ⌊ n i ⌋ ⌊ m i ⌋ i 2 ) \sum_{i=1}^n \sum_{j=1}^m (n \ \% \ i)(m \ \% \ j) \ , \ i \neq j \\ = \sum_{i=1}^n \sum_{j=1}^m ( n - \lfloor \frac{n}{i} \rfloor i) ( m - \lfloor \frac{m}{j} \rfloor j) - \sum_{ i=1 }^{min(n,m)} ( n - \lfloor \frac{n}{i} \rfloor i) ( m - \lfloor \frac{m}{i} \rfloor i ) \\ = \sum_{i=1}^n (n - \lfloor \frac{n}{i} \rfloor i) \sum_{j=1}^m (m - \lfloor \frac{m}{j} \rfloor j) - \sum_{i=1}^{min(n,m)} ( nm - n \lfloor \frac{m}{i} \rfloor i - m \lfloor \frac{n}{i} \rfloor i + \lfloor \frac{n}{i} \rfloor \lfloor \frac{m}{i} \rfloor i^2 ) i=1nj=1m(n % i)(m % j) , i=j=i=1nj=1m(nini)(mjmj)i=1min(n,m)(nini)(mimi)=i=1n(nini)j=1m(mjmj)i=1min(n,m)(nmnimimini+inimi2)

注意平方和公式:
∑ i = 1 n i 2 = n ∗ ( n + 1 ) ∗ ( 2 n + 1 ) 6 \sum_{i=1}^n i^2 = \frac{ n * (n+1) * (2n+1) }{6} i=1ni2=6n(n+1)(2n+1)

后面是整数分块能解决的啦
PS:在模的时候每一步都谨防出现负数(之前BD之星被坑了
ACcode:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#define MOD 19940417
#define inv_6 3323403//6在模意义下的逆元
#define LL long long

using namespace std;

LL getsum(LL l,LL r)
{
	return ( l+r )*( r-l+1 )/2 % MOD;
}

LL getsum2(LL x)
{
	return (x) * (x+1) % MOD * (2*x+1) % MOD * inv_6 % MOD;
}

LL cal(LL n)
{
	LL l,r,sum = 0;
	for(l=1;l<=n;l=r+1)
	{
		r = n/(n/l);
		sum = ( sum + n*(r-l+1) - getsum(l,r)*(n/l)  ) % MOD;
	}
	return ( sum + MOD ) % MOD;
}

LL n,m,ans,h1,h2,h3;
void solve()
{
	LL l,r;
	cin>>n>>m;
	if( n>m ) swap(n,m);
	ans = cal(n) * cal(m) % MOD;
	for(l =1;l<=n;l=r+1)
	{
		r = min( n/(n/l) , m/(m/l) );
		h1 = n*m % MOD * (r-l+1) % MOD;
		h2 = (n/l) * (m/l) % MOD * (getsum2(r) - getsum2(l-1)+MOD) % MOD;
		h3 = (n/l*m +m/l*n) % MOD * getsum(l,r) % MOD;
		ans = ( ans - h1 - h2 + h3  )%MOD;
		ans = (ans+MOD)%MOD; 
	}
	cout<<ans;
}

int main()
{
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值