1. 程式人生 > >hdu-1796-How many integers can you find(容斥)

hdu-1796-How many integers can you find(容斥)

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <list>

using namespace std;
typedef long long LL;
int n, m, a[15];

int gcd(int a, int b)
{
    return b == 0?a:gcd(b,a%b);
}

int main()
{
    int cnt, num, t;
    while(~scanf("%d%d",&n,&m)) {
        cnt = 0;
        for(int i = 0;i < m;i++) {
            scanf("%d",&num);
            if(num) a[cnt++] = num;
        }
        n --;
        m = cnt;
        int ans = 0;
        for(int i = 1;i < (1<<m);i++) {
            cnt = 0,  t = 1;
            for(int j = 0;j < m;j++) {
                if(i & (1<<j)) {
                    cnt ++;
                    t = t / gcd(t, a[j]) * a[j];
                    t = lcm(t,a[j]);
                }
                if(t > n){
                    break;
                }
            }
            if(cnt & 1) ans += n/t;
            else ans -= n/t;
        }
        printf("%d\n",ans);
    }
    return 0;
}
DFS 171MS
#include <iostream>//171MS	1728K
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <list>

using namespace std;
typedef long long LL;
int n, m, a[15], ans;

int gcd(int a, int b)
{
    return b == 0?a:gcd(b,a%b);
}

void dfs(int l, int p, int k)
{
    if(l > n || p >= m) return;
    if(k & 1) {
        ans += n/l;
    }
    else {
        ans -= n/l;
    }
    for(int i = p+1;i < m;i++) {
        dfs(l / gcd(l,a[i]) * a[i], i, k+1);
    }
}
int main()
{
    int cnt, num;
    while(~scanf("%d%d",&n,&m)) {
        cnt = 0;
        for(int i = 0;i < m;i++) {
            scanf("%d",&num);
            if(num) a[cnt++] = num;
        }
        n --;
        m = cnt;
        ans = 0;
        for(int i = 0;i < m;i++) {
            dfs(a[i], i, 1);
        }
        printf("%d\n",ans);
    }
    return 0;
}