BZOJ 2956 模积和

Description

求$$ \sum_{i=1}^{n} \sum_{j=1}^{m} \lbrack i \neq j \rbrack(n ; mod; i)(m ; mod ; j)$$。

Input

第一行两个数\(n,m\)

Output

一个整数表示答案\(mod\;19940417\)的值。

Sample Input

3 4

Sample Output

1

Hint

数据规模和约定

对于\(100\%\)的数据\(n,m \le 10^{9}\)

补数论中。
这题我们要从模的本质出发:$$a ; mod ; b = a - b \times \lfloor \frac{a}{b} \rfloor$$
我们首先不考虑\(i \neq j\)条件,单独对\(i\)\(j\)讨论,我们可以得到$$\sum_{i = 1}^{n}n;mod;i=\sum_{i = 1}^{n}n-i \times \lfloor \frac{n}{i} \rfloor$$
化简一下,可以得到$$\sum_{i = 1}^{n}n-i \times \lfloor \frac{n}{i} \rfloor = n{2}-\sum_{i=1}i \lfloor \frac{n}{i} \rfloor$$
由与\(\lfloor \frac{n}{i} \rfloor\)不同的只有\(\sqrt{n}\)个,这个式子可以\(O(\sqrt{n})\)计算。对于\(i,j\)分别做一遍相乘起来即可。
对于\(i=j\)的部分,单独拿出来减去贡献即可。我们用类似的方法,即求$$\sum_{i=1}^{min(n,m)}(n;mod;i)(m;mod;i)$$
然后跟之前一样的处理方法化为求$$\sum_{i=1}^{min(n,m)}(n-i \times \lfloor \frac{n}{i} \rfloor)(m - i \times \lfloor \frac{m}{i} \rfloor)$$
稍微化简一下就可以也\(\sqrt{n}\)分块了$$\sum_{i=1}^{min(n,m)}(nm - mi \lfloor \frac{n}{i} \rfloor - ni \lfloor \frac{m}{i} \rfloor + i^{2}\lfloor \frac{m}{i} \rfloor \lfloor \frac{n}{i} \rfloor)$$

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;

typedef long long ll;
#define rhl (19940417)

inline ll sum(ll a,ll b) { return (((ll)(a+b)*(ll)(b-a+1))>>1)%rhl; }

inline ll calc(ll n,ll m)
{
	ll ret = n*m%rhl;
	ll pos;
	for (ll i = 1;i <= m;i = pos+1)
	{
		pos = min(m,n/(n/i));
		(ret -= sum(i,pos)*(n/i)%rhl)%=rhl;
	}
	return ret;
}

inline ll pre(ll n)
{
	ll a = n,b = n+1,c = 2*n+1;
	return a*b%rhl*c%rhl*3323403%rhl;
}

int main()
{
	freopen("2956.in","r",stdin);
	freopen("2956.out","w",stdout);
	ll n,m;
	scanf("%lld %lld",&n,&m);
	if (n > m) swap(n,m);
	ll ans1 = calc(n,n),ans2 = calc(m,m);
	ll ans = (ans1*ans2%rhl+rhl)%rhl;
	ll pos = 1;
	for (ll i = 1;i <= n;i = pos+1)
	{
		pos = min(n,min(n/(n/i),m/(m/i)));
		(ans -= n*m%rhl*(ll)(pos-i+1))%=rhl;
		(ans += sum(i,pos)*(m*(n/(ll)i)%rhl+n*(m/(ll)i)%rhl)%rhl)%=rhl;
		(ans -= (pre(pos)-pre(i-1))%rhl*(n/(ll)i)%rhl*(m/(ll)i)%rhl)%=rhl;
	}
	printf("%lld",(ans%rhl+rhl)%rhl);
	fclose(stdin); fclose(stdout);
	return 0;
}
posted @ 2015-04-14 14:23  lmxyy  阅读(439)  评论(1编辑  收藏  举报