gdut 2016校赛决赛 Problem F 我是好人4

广工校赛时遇到这道题10E大的数打表肯定不行,起初我想到了直接相除,然后减去他们的最小公倍数,当然只限于有两个数,三个数的话就有点懵了,不知道怎么加减,四个数更别提了,而题目是50个数,当时还不知道容斥原理,怎么想也想不明白到底应该怎么写,比赛时这道题的AC的人也特别的少。赛完百度了下才知道容斥原理这个词,即:
A1并A2并A3并…..An = A1+A2+..An- ( A1交A2 + A1A3 + A1交A4 +…. An-1交An ) + (A1交A2交A3 + A1交A2交A4 + ….An-2交An-1交An) - (-1)^n*(A1交A2交A3交…An);
利用这个原理将所有情况加减一遍就算出来了。
Problem F: 我是好人4
Description
众所周知,我是好人!所以不会出太难的题,题意很简单

给你n个数,问你1000000000(含1e9)以内有多少个正整数不是这n个数任意一个的倍数
最后友情提供解题代码(我真是太好人了)
void solve(int p[], int n)
{
int ans = 0;
for (int i = 1; i <= 1e9; i++)
{
int fl = 0;
for (int j = 0; j < n; j++)
{
if (i % p[j] == 0)
{
fl = 1;
break;
}
}
if (fl == 0)ans++;
}
printf(“%d\n”, ans);
}

Input
第1行是一个整数T,表示共T组数据。 接下来是T组数据,每组数据第1行是正整数n(n<=50),接下来是n个正整数(小于等于1000),任意两数用1个空格隔开,最前数前面与最后数后面无空格

Output
输出T行,对应T组数据。(T<=10) 每行输出这样的正整数有多少个

Sample Input
342 3 5 71213854 101 143 282 538 922 946 286 681 977 892 656 907
Sample Output
228571428500000000968701719

代码:

#include
#include
#define ll long long
#define maxn 1000000000
ll a[60],b[60],k,s=0;
ll gcd(ll c, ll d)
{
    return d?gcd(d,c%d):c;
}
ll lcm(ll c,ll d)
{
    return c*d/gcd(c,d);
}
void dfs(ll qi,ll shu,ll mo)
{
    if(qi==k)
    {
        if(mo)
        {
            if(mo&1)
                s-=maxn/shu;
            else
                s+=maxn/shu;
        }
        return;
    }
    if(shu%a[qi]==0) return;
    dfs(qi+1,shu,mo);
    shu=lcm(a[qi],shu);
    if(shu<=maxn)
        dfs(qi+1,shu,mo+1);
}
int main()
{
    ll N;
    scanf("%lld",&N);
    while(N--)
    {
        k=0;
        ll j,n,i;
        scanf("%lld",&n);
        for(i=0; i"%lld",&b[i]);
        for(i=0; ifor(j=0; jif(j==i||b[j]==-1)
                    continue;
                if(b[i]==-1)
                    break;
                if(b[i]%b[j]==0)
                {
                    b[i]=-1;
                    break;
                }
            }
        }
        memset(a,0,sizeof(a));
                int f=0;
        for(i=0; iif(b[i]!=-1)
                a[k++]=b[i];
                if(b[i]==1)
                 f=1;
        }
        s=maxn;
        if(f)
        {
            printf("0\n");
            continue;
        }
        dfs(0 ,1 ,0 );
        printf("%lld\n",s);
    }
}

你可能感兴趣的:(容斥原理)