lightoj 1117 - Helping Cicada(容斥)

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 M positive 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

Output for Sample Input

2

15 3

2 3 5

10 4

2 4 5 7

Case 1: 4

Case 2: 3


题目蝉的天敌有固定的周期会来攻击蝉,蝉有m个天敌,问你在n天里,有多少天不会被攻击。

就是求去掉m个数的倍数后还有多少天。容斥一下就OK。(容斥其实就是单加双减,一般人我不告诉他。。。)

#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long

using namespace std;


LL gcd(LL a,LL b)
{
    if(b == 0)
        return a;
    return gcd(b,a%b);
}
LL lcm(LL a,LL b)
{
    return a/gcd(a,b)*b;
}
int main(void)
{
    int T,m,i,j;
    LL n;
    int a[20];
    scanf("%d",&T);
    int cas = 1;
    while(T--)
    {
        scanf("%lld%d",&n,&m);
        for(i=0;i<m;i++)
            scanf("%d",&a[i]);
        LL ans = 0;
        for(i=1;i<(1<<m);i++)
        {
            int cnt = 0;
            LL LCM = 1LL;
            for(j=0;j<m;j++)
            {
                if(i&(1<<j))
                {
                    cnt++;
                    LCM = lcm(LCM,(LL)a[j]);
                }
            }
            if(cnt&1)
                ans += n/LCM;
            else
                ans -= n/LCM;
        }
        printf("Case %d: %lld\n",cas++,n-ans);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值