hpuoj1339 容斥原理变形

OJ目前支持C/C++、Pascal语言。

1339: WitchMirror [数论]

时间限制: 1 Sec  内存限制: 128 MB

题目描述

王炸的队友地雷(你可以叫他雷雷)要考科一了,但地雷总是不太自信,因为他看的题太少了。

王炸为了帮他,就拿出来了一面魔镜,这个魔镜可以告诉雷雷他还不会的题有多少。但是魔镜自诩是hpu毕业的高材生,并不想直接了当的告诉地雷,他通过以下这种方式让地雷自己计算出来:

魔镜给地雷m个数字(a1、a2 …… am)和一个整数n,魔镜定义:如果有一个数,是这m个数字里面任意一个数的倍数,那么这个数称为LuckyNumber。而雷雷会的题数为[1,n]闭区间内LuckyNumber的数量。

那么请你帮地雷计算一下他会的题目数。

输入

有多组数据,每组数据第一行给出两个字母n、m,含义如题意所示。

数据第二行给出m个整数:a1、a2 …… am。

(1≤ n、a1、a2 …… am ≤ 1e9,1 ≤ m ≤ 15 )

输出

输出一个整数,表示地雷会的题目数。

样例输入

10 2
5 7
100 1
1

样例输出

3
100

思路:容斥裸题,注意 p[ i ] == n 的情况和 LL。

sum = 被1个数整除的个数-被2个数整除的个数+被3个数整除的个数-.... (奇加偶减);

#include<cstdio>
#include<cstring>
typedef long long LL;

LL p[1010],k;

LL gcd(LL a,LL b)
{
	return b?gcd(b,a%b):a;
}

LL lcm(LL a,LL b) 
{
	return a/gcd(a,b)*b;
}

LL nop(LL m)
{
	LL res,sum=0,use; 
	for(LL i=1;i<1<<k;i++)
	{
		res=1,use=0;
		for(LL j=0;j<k;j++)
		{
			if(i & (1<<j))
			{
				use++;
				res=lcm(res,p[j]);
			}
		}
		if(use & 1) sum+=m/res;
		else sum-=m/res;
	}
	return sum;
}

int main()
{
	LL n;
	while(scanf("%lld%lld",&n,&k)!=EOF)
	{
		for(LL i=0;i<k;i++)
		{
			scanf("%lld",&p[i]);
			if(p[i]>n)
				i--,k--;
		}
		printf("%lld\n",nop(n));
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值