1. 程式人生 > >#19. 計數(容斥原理)

#19. 計數(容斥原理)

cnblogs += void lld ring 輸入輸出 計數 define printf

時間限制:1s

內存限制:256MB

【問題述】

給出m個數a[1],a[2],…,a[m]

1~n中有多少數不是a[1],a[2],…,a[m]的倍數。

【輸入】

輸入文件名為count.in

第一行,包含兩個整數:n,m

第二行,包含m個數,表示a[1],a[2],…,a[m]

【輸出】

輸出文件名為count.out

輸出一行,包含1個整數,表示答案

【輸入輸出樣例】

count.in

count.out

10 2

2 3

3

【數據說明】

對於

60%的數據,1<=n<=106

對於另外20%的數據,m=2

對於100%的數據,1<=n<=109,0<=m<=20,1<=a[i]<=109

容斥原理

對於三個數的情況

我們需要加上每個數對答案的貢獻,減去兩兩對答案的貢獻,加上三三對答案的貢獻

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7
#define LL long long 8 using namespace std; 9 const LL MAXN=100001; 10 inline void read(LL &n) 11 { 12 char c=getchar();bool flag=0;n=0; 13 while(c<0||c>9) c==-?flag=1,c=getchar():c=getchar(); 14 while(c>=0&&c<=9) n=n*10+c-48,c=getchar();flag==1?n=-n:n=n;
15 } 16 LL gcd(LL a,LL b) 17 { 18 return b==0?a:gcd(b,a%b); 19 } 20 LL ans=0; 21 LL a[MAXN]; 22 LL n,m; 23 void dfs(LL now,LL num,LL how) 24 { 25 if(num>n) return ; 26 if(now==m+1) 27 { 28 ans+=(n/num)*how; 29 return ; 30 } 31 dfs(now+1,num,how); 32 dfs(now+1,num*a[now]/(gcd(num,a[now])),-how); 33 } 34 int main() 35 { 36 read(n);read(m); 37 for(LL i=1;i<=m;i++) 38 read(a[i]); 39 dfs(1,1,1); 40 printf("%lld",ans); 41 return 0; 42 }

#19. 計數(容斥原理)