P3455 [POI2007]ZAP-Queries

Label

利用Möbius函数改写容斥式经典题

Description

给定 Q Q Q组询问,每组询问给定三个正整数 a , b , d ( Q , a , b , d ≤ 5 × 1 0 4 ) a,b,d(Q,a,b,d\leq5\times 10^4) a,b,d(Q,a,b,d5×104),求
∑ i = 1 a ∑ j = 1 b [ g c d ( i , j ) = = d ] \sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==d] i=1aj=1b[gcd(i,j)==d]

Solution

这个题显然可以用反演做,推出来的式子和利用容斥推得的式子基本一样。此处只讲容斥做法。

在luoguP1447里,我们曾利用 f n = ⌊ a d ⌋ ⌊ b d ⌋ − ∑ i = 2 i d ≤ m i n ( a , b ) f i d f_n=\lfloor \frac{a}{d} \rfloor\lfloor \frac{b}{d} \rfloor-\sum_{i=2}^{id\leq min(a,b)}f_{id} fn=dadbi=2idmin(a,b)fid O ( n l o g n ) O(nlogn) O(nlogn) f 1 ∼ f n f_1\sim f_n f1fn ( f k = ∑ i = 1 a ∑ j = 1 b [ g c d ( i , j ) = = k ] ) (f_k=\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==k]) (fk=i=1aj=1b[gcd(i,j)==k]),但对于此题,由于 a , b a,b a,b是变化的,故若想以与P1447相同的容斥思路来解此题,那么对于每一次询问,我们都需要重新求一遍 f 1 ∼ f n f_1\sim f_n f1fn,这样一来算法总复杂度 O ( n 2 l o g n ) O(n^2logn) O(n2logn),不可取,故考虑更优的容斥方法。

之前的容斥方法是将最大公约数为 k d kd kd的数的集合从 d d d整除的数的集合中剔除掉从而得到 f d f_d fd,故此处我们考虑将原条件变形以尝试得到新的限制(约束)条件。

由于常规套路: g c d ( i , j ) = d ↔ g c d ( i d , j d ) = 1 gcd(i,j)=d\leftrightarrow gcd(\frac{i}{d},\frac{j}{d})=1 gcd(i,j)=dgcd(di,dj)=1,故首先:
∑ i = 1 a ∑ j = 1 b [ g c d ( i , j ) = = d ] ↔ ∑ i = 1 ⌊ a d ⌋ ∑ j = 1 ⌊ b d ⌋ [ g c d ( i , j ) = = 1 ] \sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==d]\leftrightarrow \sum_{i=1}^{\lfloor \frac{a}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{b}{d} \rfloor}[gcd(i,j)==1] i=1aj=1b[gcd(i,j)==d]i=1daj=1db[gcd(i,j)==1]

根据经典的容斥思路 ∣ ⋂ i = 1 n S i ∣ = ∣ U ∣ − ∣ ⋃ i = 1 n ∁ U S i ∣ |\bigcap_{i=1}^{n}S_i|=|U|-|\bigcup_{i=1}^{n}\complement_US_{i}| i=1nSi=Ui=1nUSi,考虑满足互质的有序二元组所满足的限制,其即为: ∀ ( x , y ) ∀ p ∈ p r i m e , p ∤ x ∧ p ∤ y \forall(x,y)\forall p\in prime,p\nmid x\wedge p\nmid y (x,y)pprime,pxpy

那么,令 ∁ U S i = { x ∣ p i ∣ x } \complement_US_{i}=\{x|p_i|x\} USi={xpix},且多个 ∁ U S i \complement_US_{i} USi的交= { x ∣ ∏ p i ∣ x } \{x|\prod p_i|x\} {xpix};又由于根据Möbius函数的定义,含有奇数个质因子时值为-1,偶数个质因子时值为 1 1 1,而根据此处容斥式的定义, ∏ p i \prod p_i pi内含有 p i p_i pi的个数奇偶性正好对应了容斥式内的正负;而且根据 S i S_i Si定义,含有多个相同奇因子的 i i i对应集合不予考虑,所以,我们可以利用这一点写出此题的容斥式:

D ( d ) = ∑ i = 1 ⌊ a d ⌋ ∑ j = 1 ⌊ b d ⌋ [ p ∣ i ∧ p ∣ j ] D(d)=\sum_{i=1}^{\lfloor \frac{a}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{b}{d} \rfloor}[p\mid i\wedge p\mid j] D(d)=i=1daj=1db[pipj],故:

∑ i = 1 ⌊ a d ⌋ ∑ j = 1 ⌊ b d ⌋ [ g c d ( i , j ) = = 1 ] = ∑ i = 1 m i n ( ⌊ a d ⌋ , ⌊ b d ⌋ ) μ ( i ) D ( i ) = = ∑ i = 1 m i n ( ⌊ a d ⌋ , ⌊ b d ⌋ ) μ ( i ) ⌊ a d i ⌋ ⌊ b d i ⌋ \sum_{i=1}^{\lfloor \frac{a}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{b}{d} \rfloor}[gcd(i,j)==1]=\sum_{i=1}^{min(\lfloor \frac{a}{d} \rfloor,\lfloor \frac{b}{d} \rfloor)}\mu(i)D(i)==\sum_{i=1}^{min(\lfloor \frac{a}{d} \rfloor,\lfloor \frac{b}{d} \rfloor)}\mu(i)\lfloor \frac{a}{di} \rfloor\lfloor \frac{b}{di} \rfloor i=1daj=1db[gcd(i,j)==1]=i=1min(da,db)μ(i)D(i)==i=1min(da,db)μ(i)diadib

所以
a n s = ∑ i = 1 m i n ( ⌊ a d ⌋ , ⌊ b d ⌋ ) μ ( i ) ⌊ a d i ⌋ ⌊ b d i ⌋ ans=\sum_{i=1}^{min(\lfloor \frac{a}{d} \rfloor,\lfloor \frac{b}{d} \rfloor)}\mu(i)\lfloor \frac{a}{di} \rfloor\lfloor \frac{b}{di} \rfloor ans=i=1min(da,db)μ(i)diadib

根据前面所讲的数论分块,上面这个式子可分块求,注意预处理 μ ( i ) \mu(i) μ(i)前缀和。

算法时间复杂度: O ( n n ) O(n\sqrt n) O(nn )

Code

#include<cstdio>
#include<iostream>
#define ri register int
#define ll long long
using namespace std;

const int MAXN=5e4;
int Q,cnt;
ll a,b,d,miu[MAXN+20],prime[MAXN+20],sum[MAXN+20],ans;
bool notprime[MAXN+20];

void Mobius()//利用线性筛O(n)求Mobius函数 
{
	miu[1]=1,notprime[1]=true;
	for(ri i=2;i<=MAXN;++i)
	{
		if(!notprime[i]) prime[++cnt]=i,miu[i]=-1;
		for(ri j=1;j<=cnt&&i*prime[j]<=MAXN;++j)
		{
			notprime[i*prime[j]]=true;
			if(i%prime[j]==0) break;
			else miu[i*prime[j]]=-miu[i];
		}
	}
	for(ri i=1;i<=MAXN;++i) sum[i]=sum[i-1]+miu[i];
}

int main()
{
	std::ios::sync_with_stdio(false);
	Mobius();
	cin>>Q;
	for(ri op=1;op<=Q;++op)
	{
		cin>>a>>b>>d;
		a/=d,b/=d;
		ans=0LL;
		ll l=1,r,sj=min(a,b);
		while(l<=sj)
		{
			r=min(a/(a/l),b/(b/l));
			ans+=(sum[r]-sum[l-1])*(a/l)*(b/l);
			l=r+1;
		}
		cout<<ans<<'\n';
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值