The Sports Association of Bangladesh is in great problem with their latest lottery `Jodi laiga Jai'. There
are so many participants this time that they cannot manage all the numbers. In an urgent meeting they
have decided that they will ignore some numbers. But how they will choose those unlucky numbers!!!
Mr. NondoDulal who is very interested about historic problems proposed a scheme to get free from
this problem.
You may be interested to know how he has got this scheme. Recently he has read the Joseph's
problem.
There are N tickets which are numbered from 1 to N. Mr. Nondo will choose M random numbers
and then he will select those numbers which is divisible by at least one of those M numbers. The
numbers which are not divisible by any of those M numbers will be considered for the lottery.
As you know each number is divisible by 1. So Mr. Nondo will never select 1 as one of those M
numbers. Now given N, M and M random numbers, you have to nd out the number of tickets which
will be considered for the lottery.
Input
Each input set starts with two Integers N (10 N < 231) and M (1 M 15). The next line will
contain M positive integers each of which is not greater than N.
Input is terminated by EOF.
Output
Just print in a line out of N tickets how many will be considered for the lottery.
Sample Input
10 2
2 3
20 2
2 4
Sample Output
3
10

题意: 给定一个数n 再给m个数(m<15) 假设这m个数为 a[0],a[1].....a[m-1];

    求1~n中非数组a的数的倍数的数,就是把1~n中数组a的数的倍数筛掉,剩下的数的个数就是结果。

    暴力跑会超时,利用容斥原理,比如n=10,m=2,a[0]=2,a[1]=3,把1到20中所有2的倍数筛掉,

    先令ans=n=20,ans=ans-n/2=10。再把1到20中所有3的倍数筛掉,ans=ans-n/3=4。

    那么现在问题来了,这么筛选的话会导致2和3的公倍数进行了二次筛选,也就是6,12,18这三个数,

    所以要把这三个数加回来,ans=ans+n/(2*3)=7,得出最终结果。以此类推,数的个数为奇数就减,

    数的个数为偶数就加,这就是容斥原理。

注意 :本题给的数不一定为质数,也可能为合数,上述容斥原理适用于质数,

     在本题中进行容斥原理时要用他们的最小公倍数lcm。

    比如n=10,m=2,a[0]=2,a[1]=4,这组数据,可验证本题要用lcm,而不是a[0]*a[1]。

第一种方法:搜索遍历

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
if(b==) return a;
return gcd(b,a%b);
}
ll lcm(ll a,ll b)
{
return a/gcd(a,b)*b;
}
ll n,m,a[],ans=;
void dfs(ll hav,ll cur,ll num)
{
if(hav>n||cur>=m)
return ;
for(int i=cur;i<m;i++) //注意区分这里的i和主函数里的i 混了就错了
{
ll temp=lcm(hav,a[i]);
if(num&)
ans=ans-n/temp;
else
ans=ans+n/temp;
dfs(temp,i+,num+);
}
}
int main()
{
while(cin>>n>>m)
{
memset(a,,sizeof(a));
for(int i=;i<m;i++)
cin>>a[i];
ans=n;
for(int i=;i<m;i++)
{
ans=ans-n/a[i];
dfs(a[i],i+,);
}
cout<<ans<<endl;
}
}

注意在上述代码中,不可以将主函数中的

for(int i=0;i<m;i++)
{
ans=ans-n/a[i];
dfs(a[i],i+1,2);
}
改为

for(i=0;i<m;i++)
{
dfs(a[i],i,1);
}

因为这样枚举情况会变多,原意指的是对于这m个数来说,一定包含这个数,dfs枚举是否包含其他数。

这个是初始化ans=n的,至于初始化ans=0怎么做还没弄懂,求高人指点。

感觉这个搜索应该还有另一种写法用select[i]=1,dfs,select[i]=0这样。

第二种方法:二进制枚举

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
if(b==) return a;
return gcd(b,a%b);
}
ll lcm(ll a, ll b)
{
return a/gcd(a,b)*b;
}
int main()
{
ll n,m,a[];
while(cin>>n>>m)
{
memset(a,,sizeof(a));
for(int i=;i<m;i++)
cin>>a[i];
ll ans=;
for(int i=;i<(<<m);i++)
{
ll tmp=,flag=;
for(int j=;j<m;j++)
{
if(i&(<<j))
{
tmp=lcm(tmp,a[j]); //注意是a[j]
//if(tmp>n) 这两句话可有可无 n/tmp=0;
//break;
flag++;
}
}
if(flag&)
ans=ans-n/tmp;
else
ans=ans+n/tmp;
}
cout<<ans<<endl;
}
return ;
}

UVA 10325 The Lottery( 容斥原理)的更多相关文章

  1. UVA.10325 The Lottery (组合数学 容斥原理 二进制枚举)

    UVA.10325 The Lottery (组合数学 容斥原理) 题意分析 首先给出一个数n,然后给出m个数字(m<=15),在[1-n]之间,依次删除给出m个数字的倍数,求最后在[1-n]之 ...

  2. 容斥原理——uva 10325 The Lottery

    首先推荐一篇介绍容斥原理很好的博客http://www.cppblog.com/vici/archive/2011/09/05/155103.html 题意:求1~n中不能被给定m个数中任意一个数整除 ...

  3. UVA 10325 - The Lottery(容斥)

    以前做过的一个题,忘记/gcd了,看来需要把以前的东西看一下啊. #include <cstdio> #include <cstring> #include <iostr ...

  4. UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举)

    UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举) 题意分析 给出n*m的矩形格子,给出k个点,每个格子里面可以放一个点.现在要求格子的最外围一圈的每行每列,至少要放一个 ...

  5. UVA 10325 lottery 容斥原理

    题目链接 给出m个数, 求1-n的范围内, 无法整除这m个数之中任何一个数的数的个数. 设m个数为a[i], 对任意的i, n/a[i]是n中可以整除a[i]的数的个数, 但是这样对于有些数重复计算了 ...

  6. UVA 11806 Cheerleaders (容斥原理

    1.题意描述 本题大致意思是讲:给定一个广场,把它分为M行N列的正方形小框.现在给定有K个拉拉队员,每一个拉拉队员需要站在小框内进行表演.但是表演过程中有如下要求: (1)每一个小框只能站立一个拉拉队 ...

  7. UVa 11806 拉拉队(容斥原理)

    https://vjudge.net/problem/UVA-11806 题意: 在一个m行n列的矩形网格里放k个相同的石子,有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行.最后一 ...

  8. UVa 11806 Cheerleaders (数论容斥原理)

    题意:给定一个n*m的棋盘,要放k个石子,要求第一行,最后一行,第一列,最后一列都有石子,问有多少种放法. 析:容斥原理,集合A是第一行没有石子,集合B是最后一行没有石子,集合C是第一列没有石子,集合 ...

  9. uva 10325基础容斥

    题目:给你一个数n以及m个数字,问1~n中不能被这m个数字整除的数字的个数. 分析:容斥原理.组合数学.数字1-n中能被a.b整除的数字的个数分别是n/a,n/b: 则1-n中能被a或b整数的数字个数 ...

随机推荐

  1. BZOJ-4424 &&CodeForces-19E Fairy DP+dfs (Link-Cut-Tree可A)

    Va爷的胡策题T2 E. Fairy time limit per test1.5 seconds memory limit per test256 megabytes inputstandard i ...

  2. 学习笔记--博弈组合-SG函数

    fye学姐的测试唯一的水题.... SG函数是一种游戏图每个节点的评估函数 具体定义为: mex(minimal excludant)是定义在整数集合上的操作.它的自变量是任意整数集合,函数值是不属于 ...

  3. foeach集合遍历

    package number; public class Number { public static void main(String[] args) { int[] arr={5,2,1,0,3, ...

  4. C# 抓取网页Html源码 (网络爬虫)

    http://www.cnblogs.com/wxxian001/archive/2011/09/07/2169519.html 刚刚完成一个简单的网络爬虫,因为在做的时候在网上像无头苍蝇一样找资料. ...

  5. linux3

    第一课:date +%Y-%m-%d 显示日期date +%H:%M 显示小时分钟date 显示日期 vi /etc/sysconfig/network-scripts/ifcfg-eth0 网卡配置 ...

  6. 初学structs2,表单验证简单补充

    一.使用注解方式,跳过验证某个方法 由于在开发中,我们不需在请求每一个action类中的方法时都要走validate方法,那么我们可以在这些不需要验证的方法上加上@SkipValidation注解即可 ...

  7. java中request,application,session三个域及参数简单示例

    直接上代码: java代码: public class HelloAction implements Action { @Override public String execute() throws ...

  8. tp框架查询

    <?php namespace Admin\Controller; use Think\Controller; class MainController extends Controller { ...

  9. Developing a plugin framework in ASP.NET MVC with medium trust

    http://shazwazza.com/post/Developing-a-plugin-framework-in-ASPNET-with-medium-trust.aspx January 7, ...

  10. spring 标注 详解

    http://snowolf.iteye.com/blog/578452 http://snowolf.iteye.com/blog/578452  非常棒的入门读物