B - Number Puzzle ZOJ - 2836(容斥原理 数学)

Given a list of integers (A1, A2, …, An), and a positive integer M, please find the number of positive integers that are not greater than M and dividable by any integer from the given list.

Input
The input contains several test cases.

For each test case, there are two lines. The first line contains N (1 <= N <= 10) and M (1 <= M <= 200000000), and the second line contains A1, A2, …, An(1 <= Ai <= 10, for i = 1, 2, …, N).

Output
For each test case in the input, output the result in a single line.

Sample Input
3 2
2 3 7
3 6
2 3 7

Sample Output
1
4
抽空起来整理训练的题目,还是容斥原理.这次看就比原来明白多了…
怎么说呢,感觉容斥原理本质上就是加奇减偶.然后我们根据题意去在这个基础上做一些改变.这个题目的本意是,给你n个数,再给你一个m,找出不大于m,而且至少能被这n个数中一个数整除的数的个数.典型的容斥定理,a+b+c-ab-ac-bc+abc…就是这样奇加偶减.dfs做就可以了.集体解释看代码.
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;

const int maxx=11;
ll n,m,ans;
ll vis[maxx];
ll b[maxx];
int cnt;

ll gcd(ll x,ll y)//求gcd,最大公因数
{
	if(x%y==0) return y;
	else return gcd(y,x%y);
}

ll lcm(ll x,ll y)//最小公倍数
{
	return x/gcd(x,y)*y;
}

void dfs(ll cur,ll ant,ll num)//ant代表数组下标,防止重复搜索..num代表几个数字..来进行奇加偶减
{
	if(cur>m||num>cnt) return ;
	for(int i=ant;i<cnt;i++)
	{
		ll temp=lcm(cur,b[i]);
		if(num%2) ans+=m/temp;
		else ans-=m/temp;
		dfs(temp,i+1,num+1);
	}
}
int main()
{
	while(scanf("%lld%lld",&n,&m)!=EOF)
	{
		memset(vis,0,sizeof(vis));
		cnt=0;
		for(int i=0;i<n;i++)
		{
			ll a;
			scanf("%lld",&a);
			if(!vis[a])//为了避免重复,这样处理一下..
			{
				vis[a]=1;
				b[cnt++]=a;
			}
		}
		ans=0;
		for(int i=0;i<cnt;i++)
		{
			ans+=m/b[i];//先把单个的加起来.
			dfs(b[i],i+1,2);
		}
		printf("%lld\n",ans);
	}
}

容斥原理要多思考.推出公式来就好了…
努力加油a啊,(o)/~.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值