程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> SDUT 3023-當N遇上M(容斥原理)

SDUT 3023-當N遇上M(容斥原理)

編輯:C++入門知識

SDUT 3023-當N遇上M(容斥原理)


題目鏈接:傳送門

題意:求[1,n]內與m互質的個數。

容斥原理:奇加偶減(奇數個類的計數和-偶數個類的計數和)

對於這個問題,首先求出m的質因數fac[] , 然後所在區間內有n/fac[i]個數 一定不能與m互質(比如m=8,n=10,對於fac[]=2,有2,4,6,8,10 即5(10/2)個數不能與8互質)。。枚舉每一個質因數選還是不選。可以位運算,也可以dfs

第一發容斥,准備系統的刷一下容斥的專題了。。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define maxn 360
#define _ll __int64
#define ll long long
#define INF 0x3f3f3f3f
#define Mod 1000000007
#define pp pair
#define ull unsigned long long
#define max(x,y) ( ((x) > (y)) ? (x) : (y) )
#define min(x,y) ( ((x) > (y)) ? (y) : (x) )
using namespace std;
ll fac[1111],tot,ans;
void div(ll x)//分解質因數
{
	tot=0;
	for(ll i=2;i*i<=x;i++)
	{
		if(x&&x%i==0)
		{
			fac[tot++]=i;
			while(x&&x%i==0)
				x/=i;
		}
	}
	if(x>1)
		fac[tot++]=x;
}
void dfs(ll num,ll s,ll r,ll n)//n為范圍 即(1,n)
{
	if(num==tot)
	{
		if(s&1)ans-=n/r;//容斥原理:奇加偶減(那這裡為什麼還是減?因為n/r是不能和m互質的個數啦)
		else ans+=n/r;
		return ;
	}
	dfs(num+1,s,r,n);
	dfs(num+1,s+1,r*fac[num],n);
}
int main()
{
	ll n,m;
	while(~scanf("%lld%lld",&n,&m))
	{
		ans=0;div(m);
		dfs(0,0,1,n);
		printf("%lld\n",ans);
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved