UVA 10325 The Lottery( 容斥原理)
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( 容斥原理)的更多相关文章
- UVA.10325 The Lottery (组合数学 容斥原理 二进制枚举)
UVA.10325 The Lottery (组合数学 容斥原理) 题意分析 首先给出一个数n,然后给出m个数字(m<=15),在[1-n]之间,依次删除给出m个数字的倍数,求最后在[1-n]之 ...
- 容斥原理——uva 10325 The Lottery
首先推荐一篇介绍容斥原理很好的博客http://www.cppblog.com/vici/archive/2011/09/05/155103.html 题意:求1~n中不能被给定m个数中任意一个数整除 ...
- UVA 10325 - The Lottery(容斥)
以前做过的一个题,忘记/gcd了,看来需要把以前的东西看一下啊. #include <cstdio> #include <cstring> #include <iostr ...
- UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举)
UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举) 题意分析 给出n*m的矩形格子,给出k个点,每个格子里面可以放一个点.现在要求格子的最外围一圈的每行每列,至少要放一个 ...
- UVA 10325 lottery 容斥原理
题目链接 给出m个数, 求1-n的范围内, 无法整除这m个数之中任何一个数的数的个数. 设m个数为a[i], 对任意的i, n/a[i]是n中可以整除a[i]的数的个数, 但是这样对于有些数重复计算了 ...
- UVA 11806 Cheerleaders (容斥原理
1.题意描述 本题大致意思是讲:给定一个广场,把它分为M行N列的正方形小框.现在给定有K个拉拉队员,每一个拉拉队员需要站在小框内进行表演.但是表演过程中有如下要求: (1)每一个小框只能站立一个拉拉队 ...
- UVa 11806 拉拉队(容斥原理)
https://vjudge.net/problem/UVA-11806 题意: 在一个m行n列的矩形网格里放k个相同的石子,有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行.最后一 ...
- UVa 11806 Cheerleaders (数论容斥原理)
题意:给定一个n*m的棋盘,要放k个石子,要求第一行,最后一行,第一列,最后一列都有石子,问有多少种放法. 析:容斥原理,集合A是第一行没有石子,集合B是最后一行没有石子,集合C是第一列没有石子,集合 ...
- uva 10325基础容斥
题目:给你一个数n以及m个数字,问1~n中不能被这m个数字整除的数字的个数. 分析:容斥原理.组合数学.数字1-n中能被a.b整除的数字的个数分别是n/a,n/b: 则1-n中能被a或b整数的数字个数 ...
随机推荐
- BZOJ-2875 随机数生成器 矩阵乘法快速幂+快速乘
题目没给全,吃X了... 2875: [Noi2012]随机数生成器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 1479 Solved: 829 ...
- android 自定义控件 使用declare-styleable进行配置属性(源码角度)
android自定义styleableattrs源码 最近在模仿今日头条,发现它的很多属性都是通过自定义控件并设定相关的配置属性进行配置,于是便查询了解了下declare-styleabl ...
- 如果您想省略JS里的分号,了解一下JS的分号插入原理吧
仅在}之前.一个或多个换行之后和程序输入的结尾被插入 也就是说你只能在一行.一个代码块和一段程序结束的地方省略分号. 也就是说你可以写如下代码 function square(x) { var n = ...
- _stdcall与_cdecl(了解)
调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用而建立的一种协议.这种协议规定了该语言的函数中的参数传送方式.参数是否可变和由谁来处理堆栈等问题.不同的语言定义了不 ...
- C++命名空间
C++命名空间 本讲基本要求 * 掌握:命名空间的作用及定义:如何使用命名空间. * 了解:使用早期的函数库 重点.难点 ◆命名空间的作用及定义:如何使用命名空间. 在学习本书 ...
- hdu 2049 不容易系列之(4)——考新郎
在本博AC代码中,求CNM用的是Anm/amm没用阶乘的形式,两者皆可 #include <stdio.h> int main(void) { long long a,b,larr[21] ...
- dede5.7前台插入恶意JS代码
这个问题应该很久了 最近发现有用这个的蠕虫,dede 前台提交友情链接 只用htmlspecialchars简单处理了一下 可以插入代码plus/flink_add.php 提交: 表单中提交 图片地 ...
- SQL注入攻击技巧总结
0×01 你要知道目前有哪些数据库 微软公司旗下的: Microsoft SQL server 简称 MS-SQL 或者 SQL SERVER (大型数据库操作,功能和性能异常强大)(一般也是ASP或 ...
- web.config 加密/解密
(Aspnet_regiis.exe) 这样的一个工具,可以对站点的.config文件的节进行加密 方法: #> 加密:aspnet_regiis -pef "加密的web.confi ...
- C# 设置开机自动启动(注册表方式)
.NET技术交流群 199281001 .欢迎加入. using System; using System.Collections.Generic; using System.Linq; using ...