hdu-1796
http://acm.hdu.edu.cn/showproblem.php?pid=1796? ?
題意:給你兩個(gè)數(shù)n,m,即讓你從1~n-1個(gè)數(shù)里有多少個(gè)能整除m個(gè)數(shù)中任意一個(gè)數(shù)?
題解:容斥原理:ORZ vici大牛寫的比較詳細(xì) ??http://www.cppblog.com/vici/archive/2011/09/05/155103.html#userconsent#
?
/*********************************************************** * 容斥原理 * * 求幾個(gè)數(shù)的組合(用二進(jìn)制優(yōu)化枚舉各個(gè)狀態(tài))的最小公倍數(shù), * 用n/lcm,如果這幾個(gè)數(shù)的個(gè)數(shù)為奇數(shù)則加,偶數(shù)則減, * 注:當(dāng)這幾個(gè)數(shù)有0時(shí),先把0給去掉 * * * * ***********************************************************/ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; typedef long long LL; int st[15]; LL n; LL Gcd(LL a,LL b){//最大公約數(shù)return b == 0 ? a : Gcd(b,a%b); } LL Lcm(LL a,LL b){//最小公倍數(shù)return a * b / Gcd(a,b); } LL find(int num){//尋找組合int cnt = 0,c = 0;LL lcm = 1;while(num){if(num & 1) {lcm = Lcm(lcm,(LL)st[cnt]);c++;}cnt ++;num /= 2;}LL ans = (n-1) / lcm;if(c % 2) return ans;return -ans; } void solve(int m){//枚舉各個(gè)狀態(tài)二進(jìn)制優(yōu)化LL sum = 0;for(int i = 1;i < (1 << m) ;i++){sum += find(i);}cout << sum << endl; } int main(){ // freopen("1.txt","r",stdin);int x,m;while(cin >> n >> m){int k = 0;for(int i = 0;i < m;i++){cin >> x;if(x) //如果存在0,先排除 st[k ++] = x;}solve(k);} }總結(jié)
- 上一篇: poj - 2356 Find a mu
- 下一篇: Ural 1207. Median on