题意:[1,n-1]中有多少被m集合里的数整除。
分析:容斥水题,注意m中可能有不互质的数。
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 1000005
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int read() {
char c;
int ans=0,f=1;c=getchar();
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {ans=ans*10+c-'0';c=getchar();}
return ans*f;
}
int a[30],tot,n;
ll sum;
ll gcd(ll a,ll b) {
if(b) return gcd(b,a%b);
return a;
}
void dfs(int num,int pos,ll lcm) {
lcm=lcm*a[pos]/gcd(lcm,a[pos]);
if(num%2) sum+=(n-1)/lcm;
else sum-=(n-1)/lcm;
for(int i=pos+1;i<=tot;i++) {
dfs(num+1,i,lcm);
}
}
int main() {
int m;
while(~scanf("%d%d",&n,&m)) {
tot=0;sum=0;
for(int i=1;i<=m;i++) {
int x=read();
if(x) a[++tot]=x;
}
for(int i=1;i<=tot;i++)
dfs(1,i,a[i]);
printf("%I64d\n",sum);
}
return 0;
}