uva 10325基础容斥
题目:给你一个数n以及m个数字,问1~n中不能被这m个数字整除的数字的个数。
分析:容斥原理、组合数学。数字1-n中能被a、b整除的数字的个数分别是n/a,n/b;
则1-n中能被a或b整数的数字个数为n/a + n/b - n/lcm(a,b),
(最后一项为同时被a、b整除的数字个数);
推广后可知能被m个数整除的个数是
分别整除 - 任意两数的lcm + 任意三个数的lcm - 任意四个数的lcm + ...
ac代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; typedef long long ll; ll num[16]; ll gcd(ll a,ll b) { if(b==0) return a; return gcd(b,a%b); } ll lcm(ll a,ll b) { ll g=gcd(a,b); return a/g*b; } void solve(int n,int m) { ll sum=0; for(int i=1;i<(1<<m);i++)// 二进制枚举 { // cout<<i<<": "; int ret=0; ll temp=1; for(int j=0;j<m;j++) { if(i&(1<<j)) // { // cout<<num[j]<<" "; ret++; temp=lcm(temp,num[j]); } } // cout<<endl; if(ret%2) sum+=(n/temp); else sum-=(n/temp); } cout<<n-sum<<endl; } int main() { ll n; int m; while(cin>>n>>m) { for(int i=0;i<m;i++) cin>>num[i]; // for(int i=0;i<ret;i++) cout<<num[i]<<' '; solve(n,m); } return 0; }