bzoj 2154 && bzoj 2693

题意:

求ΣΣlcm(i,j)

2693:多组询问


ans = ΣΣlcm(i,j) = ΣΣΣx*y*d  (gcd(x,y) == 1) = ΣdΣΣx*y

令F[x][y] = ΣΣx*y(gcd(x,y) == 1)

莫比乌斯反演

F[x][y] = Σk^2*u(k)*sum[x/k][y/k]

sum[i][j] = ΣΣi*j

上式可以通过容斥证明

这样O(n)回答,,过2154


进一步优化

令D = kd

带进去,化化化化化

ans = Σsum[n/D][m/D]*ΣD*k*u(k) (k|D)


可以证明,g[k] = k*u(k) (k|D)是个积性函数

又,,积性函数的约数和也是积性函数

所以右边那坨是个积性函数,线性筛之

令h[D] = ΣD*k*u(k) (k|D)

筛法进行时  出现i%prime[j] == 0的情况时,和积性函数性质冲突

此时,令T = i*prime[j]

可以证明h[T] = prime[j]*h[i]

为什么呢?

因为T关于i,多出来的约数全部是满足u(k) = 0的

这部分忽略

而其它重合的东西

ΣD*k*u(k) (k|D)中

有T = i*prime[j]啊


代码是两题互刷的,,,


#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
using namespace std;

const int maxn = 1E7 + 10;
typedef long long LL;
const LL mo = 20101009;

LL n,m,k[maxn];
int tot,mu[maxn],prime[maxn];
bool not_prime[maxn];

LL Sum(LL x,LL y)
{
	x %= mo; y %= mo; 
	LL R1 = ((1+x)*x>>1)%mo;
	LL R2 = ((1+y)*y>>1)%mo;
	return R1*R2%mo;
}

int main()
{
	#ifdef DMC
		freopen("table1.in","r",stdin);
	#endif
	
	k[1] = 1;
	for (LL i = 2; i < maxn; i++) {
		if (!not_prime[i]) {
			k[i] = i*(1-i + mo) % mo; 
			prime[++tot] = i;
		}
		for (int j = 1; prime[j]*i < maxn; j++) {
			not_prime[prime[j]*i] = 1;
			if (i % prime[j] == 0) {
				k[i*prime[j]] = 1LL*prime[j]*k[i]%mo; 
				break;
			}
			k[prime[j]*i] = k[prime[j]]*k[i]%mo;
		}
	}
	for (LL i = 1; i < maxn; i++) k[i] = (k[i] + k[i-1]) % mo;
	
		scanf("%lld%lld",&n,&m);
		LL last,tail = min(n,m);
		LL ans = 0;
		for (LL i = 1; i <= tail; i = last + 1) {
			last = min(n/(n/i),m/(m/i));
			ans = (ans + Sum(n/i,m/i)*(k[last] - k[i-1] + mo)%mo)%mo;
		}
		printf("%lld",(ans + mo) % mo);
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值