1. 程式人生 > >hdu4135 Co-prime(容斥原理)

hdu4135 Co-prime(容斥原理)

題意:給定一個左端點L,右端點R,問L-R間有多少個數與N互質,注意1與任何數均互質。

題解:容斥原理,對N分解質因數,然後容斥原理找出這些質因數的倍數的個數,即與N不互質的數,

分別統計1-R中不互質,1-(L-1)中不互質,二者作差即為L-R中不互質,再用區間長度減去即為互質的個數。

Status Accepted
Time 15ms
Memory 1748kB
Length 1464
Lang C++
Submitted 2018-09-16 11:32:49
Shared
RemoteRunId 26288227

Select Code

#include <iostream>
#include <algorithm> 
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <bitset> 
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-7;
typedef long long ll;
#define vi vector<int> 
#define si set<int>
#define pii pair<int,int> 
#define pi acos(-1.0)
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define sci(x) scanf("%d",&(x))
#define scll(x) scanf("%lld",&(x))
#define sclf(x) scanf("%lf",&(x))
#define pri(x) printf("%d",(x))
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define mem(a,b) memset(a,b,sizeof(a)) 
using namespace std;
ll l,r,m,num,a[40],len,ans;
ll factor(ll n)
{
	ll num=0;
	for(ll i=2;i*i<=n;++i)
	{
		if(n%i==0&&n)
		{
			a[num++]=i;
			while(n%i==0&&n)n/=i;
		}
	}
	if(n>1)a[num++]=n;
	return num;
}
ll func(ll up1,ll up2,ll m)
{
	ll ans1=0,ans2=0,tmp,flag;
	rep(i,1,(1<<m)-1)
	{
		tmp=1,flag=0;
		rep(j,0,m-1)
		{
			if(i&(1<<j))
			{
				++flag;
			    tmp*=a[j];
			}
		}
		if(flag&1)ans1+=up1/tmp,ans2+=up2/tmp;
		else ans1-=up1/tmp,ans2-=up2/tmp;
	}
	return ans2-ans1;
}
void init()
{
	num=0;
	mem(a,0);
}
int main()
{
   int t;
   sci(t);
   rep(k,1,t)
   {
   	init();
	scanf("%lld%lld%lld",&l,&r,&m);
	len=r-l+1;
	num=factor(m);
	ans=len-func(l-1,r,num);//無需特判素數 分解自有天意 
	printf("Case #%d: %lld\n",k,ans);
   }
   return 0;
}