「HDU 4135」题解

Description

Link

求出给定区间 [A,B] 中与 N 互质的数的个数。
其中, \(1\leq A,B\leq10^{15}\)\(1\leq N\leq10^9\)


Solution

这种区间查询操作容易转化成前缀相减操作。
\(\operatorname{Ans[A]}\) 表示 \(\operatorname{[1,A] }\) 中与 N 互质的个数,\(\operatorname{Ans[B-1]}\) 表示 \(\operatorname{[1,B-1] }\) 中与 N 互质的个数。
答案就是 \(\operatorname{Ans[A]}-\) \(\operatorname{Ans[B-1]}\)
那么问题就转化为了求 \(\operatorname{[1,M]}\) 中与 N 互质的个数。此时就不能从欧拉函数来考虑。
考虑容斥,因为与 N 互质的数 X,\(\operatorname{(X,N)}=1\),两者不含相同因子。
由唯一分解定理可知,设 X=\(\sum_{i=1}^np_i^{k_i}\) (\(p_i\) 表示质因数)。
设其中与 N 重复的质因数有 \(p_i\),\(p_j\),\(p_k\)...\(p_m\)
由容斥定理可得:
\(\operatorname{Ans[m]}\)=\(m\) \(-\) \(\sum_{i=1}^m\lfloor \frac{N}{p_i} \rfloor\) \(+\) \(\sum_{i=1}^m\sum_{j=i+1}^m\lfloor \frac{N}{p_ip_j} \rfloor\)...
因为 N 的质因子个数不超过 \(\log(N)\) 个,所以枚举的时间复杂度小于 \(\Theta(\sqrt N)\)
总时间复杂度:\(\Theta(T\sqrt N)\)
Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=1e6;
#define int long long
int t,a,b,n,cnt,k,mp[MAXN+5],p[MAXN+5],ans[MAXN+5],num[MAXN+5],phi[MAXN+5],sum[MAXN+5],v[MAXN+5],tot,pp;
bool vis[MAXN+5];
void Work(int x)
{
	tot=0;
	for(int i=2;i*i<=x;i++)
	{
		if(x%i==0)
		{
			v[++tot]=i;
			while(x%i==0)
			{
				x/=i;
			}
		}
	}
	if(x!=1)
	{
		v[++tot]=x;
	}
}
void dfs(int now,int &V,int res,int up,int cc)
{
	if(now>tot)
	{
		if(!cc)
		{
			return;
		}
		if(cc&1)
		{
			V-=up/res;
		}
		else{
			V+=up/res;
		}
		return;
	}
	dfs(now+1,V,res*v[now],up,cc+1);
	dfs(now+1,V,res,up,cc);
}
int Ans(int x)
{
	if(!x)
	{
		return 0;
	}
	int val=x,cc=0;
	dfs(1,val,1,x,cc);
	return val;
}
signed main()
{
	scanf("%lld",&t);
	while(t--){
		scanf("%lld%lld%lld",&a,&b,&n);
		Work(n);
		printf("Case #%lld: %lld\n",++pp,Ans(b)-Ans(a-1));
	}
	return 0;
}

\(\Bbb{End.}\)
\(\Bbb{Thanks}\) \(\Bbb{For}\) \(\Bbb{Reading.}\)

posted @ 2021-08-17 21:34  StranGePants  阅读(41)  评论(0编辑  收藏  举报