题目链接:传送门
题意:求[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 <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype> #include <vector> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define maxn 360 #define _ll __int64 #define ll long long #define INF 0x3f3f3f3f #define Mod 1000000007 #define pp pair<int,int> #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; }
时间: 2024-10-07 06:07:18