二进制枚举+容斥原理

Cicada is an insect with large transparent eyes and well-veined wings similar to the "jar flies". The insects are thought to have evolved 1.8 million years ago during the Pleistocene epoch. There are about 2,500 species of cicada around the world which live in temperate tropical climates.

These are all sucking insects, which pierce plants with their pointy mouthparts and suck out the juices. But there are some predators (like birds, the Cicada Killer Wasp) that attack cicadas. Each of the predators has a periodic cycle of attacking Cicadas. For example, birds attack them every three years; wasps attack them every 2 years. So, if Cicadas come in the 12th year, then birds or wasps can attack them. If they come out in the 7th year then no one will attack them.

So, at first they will choose a number N which represents possible life-time. Then there will be an integer M indicating the total number of predators. The next M integers represent the life-cycle of each predator. The numbers in the range from 1 to N which are not divisible by any of those M life-cycles numbers will be considered for cicada's safe-emerge year. And you want to help them.

Input

Input starts with an integer T (≤ 125), denoting the number of test cases.

Each case contains two integers N (1 ≤ N < 231) and M (1 ≤ M ≤ 15). The next line contains Mpositive integers (fits into 32 bit signed integer) denoting the life cycles of the predators.

Output

For each test case, print the case number and the number of safe-emerge days for cicada.

Sample Input

2

15 3

2 3 5

10 4

2 4 5 7

Sample Output

Case 1: 4

Case 2: 3

给你一组数和一个n,找出不是1-n中不是这些数倍数的数的个数。例如

15 3

2 3 5

二进制枚举,奇加偶减。

看一下代码..................................

m个数,共有2的m次方个状态,例如m=3,那么它有以下几种情况:

000 001 010 011 101 110 111 其中1带表选择,0带表不选。

奇加偶减,那个二重循环就是上面的这个意思 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100];//ooo//
ll gcd(ll x,ll y)
{
    return y==0?x:gcd(y,x%y);////
}
ll lcm(ll x,ll y)
{
    return x/gcd(x,y)*y;//
}
int main()
{
    ll t;
    scanf("%lld",&t);
    ll tt=0;
    while(t--)
    {
        ll n,m;
        //memset(dp,0,sizeof(dp));
        scanf("%lld%lld",&n,&m);//
        //ll ok=ans[n];
        for(ll i=0; i<m; i++)
        {
            scanf("%lld",&a[i]);
            //sum-=n/a[i];
            //cout<<sum<<"Dddd"<<endl;
        }
        ll ans=0;
        for(ll i=1; i<(1<<m); i++)
        {
            int cnt=0;
            ll Lcm=1ll;
            for(ll j=0; j<m; j++)
            {
                if(i&(1<<j))
                {
                    cnt++;
                    Lcm=lcm(Lcm,a[j]);
                }
            }
            if(cnt&1)
                ans+=n/Lcm;
            else
                ans-=n/Lcm;//
        }
        printf("Case %lld: %lld\n",++tt,n-ans);
    }
}

 

 

猜你喜欢

转载自blog.csdn.net/lanshan1111/article/details/88831377