链接:https://www.nowcoder.com/acm/contest/135/A
来源:牛客网

若一个集合A内所有的元素都不是正整数N的因数,则称N与集合A无关。

  给出一个含有k个元素的集合A={a1,a2,a3,...,ak},求区间[L,R]内与A无关的正整数的个数。
  保证A内的元素都是素数

输入描述:

输入数据共两行:

第一行三个正整数L,R,k,意义如“题目描述”。

第二行k个正整数,描述集合A,保证k个正整数两两不相同。

输出描述:

输出数据共一行:

第一行一个正整数表示区间[L,R]内与集合A无关的正整数的个数

输入例子:
1 10 4
2 3 5 7
输出例子:
1

-->

示例1

输入

复制

1 10 4
2 3 5 7

输出

复制

1
示例2

输入

复制

2 10 4
2 3 5 7

输出

复制

0

说明

对于30%的数据:1<=L<=R<=10^6

对于100%的数据:1<=L<=R<=10^18,1<=k<=20,2<=ai<=100

分析:直接计算无关的数,要枚举计算,量很大。所以考虑转化成计算有关的数,然后用总数减去有关的数就是无关的数
如我们要计算l到r的无关的数,就等于r-l+1-(f(r)-f(l-1)),其中f(x)代表1到x的有关的数
然后计算有关的数,考虑计算有关数的时候会出现像6这样既是2的倍数又是3的倍数的数,所以我们在计算的过程中要用容斥原理来去重
这里我们考虑用二进制状态的方法来计算每个数的容斥
last=(1<<k)-1,然后通过与(1<<j)(0<=j<k)进行二进制与运算来保证循环的过程中,我们依次计算了a[0],a[0]*a[1],...,a[0]*a[1]*...*a[k-2]*a[k-1]的倍数
计算出这些数有多少个倍数后用容斥原理的奇加偶减计算最后的结果
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define debug(a) cout << #a << " " << a << endl
using namespace std;
const int maxn = 25;
const int mod = 1e9 + 7;
typedef long long ll;
ll a[maxn], k;
ll solve( ll n ) { //求1到n区间和集合a有关的数的个数
if( n == 0 ) { //特判一下1到0区间不存在,所以满足条件的数的个数当然是0
return 0;
}
ll ans = 0, last = ( 1 << k ) - 1;
//用二进制数的二进制位表示集合a里每个数的使用状态,1表示使用了,
//0表示没使用,对应二进制的第一位对应的是第一个数的使用状态,
//last表示的是k个数的最后一个枚举方式1..1,(k个1)
for( ll sta = 1; sta <= last; sta ++ ) { //这里从状态从1枚举到last,刚好把k个数的全部状态枚举了一遍
ll cnt = 0; //记录当前枚举的状态里使用的数的个数
ll flag = 0;
ll tmp = 1; //tmp存的是枚举到的数的最小公倍数
for( ll j = 0; j < k; j ++ ) {
if( sta&(1<<j) ) {
cnt ++;
tmp *= a[j];
if( tmp > n ) {
flag = 1;
break;
}
}
}
if( flag ) {
continue;
}
if( cnt&1 ) { //根据容斥定理,求k个集合的并集的元素个数时是奇加偶减
ans += n/tmp;//我们要求的是这cnt个数,假设是a2,a4,a5,要求这些数在1到n的公共倍数有多少个,
//就要先求出这cnt个数的lcm然后n/lcm即可,这里题目保证了a数组每个数都是质数,所以cnt个数的乘积即是对应的lcm
} else {
ans -= n/tmp;
}
}
return ans;
}
int main() {
ll le, ri;
while( cin >> le >> ri >> k ) {
for( ll i = 0; i < k; i ++ ) {
cin >> a[i];
}
cout << ri-le+1-(solve(ri)-solve(le-1)) << endl;
}
return 0;
}

  

牛客小白赛5 无关(relationship) 容斥原理(计算因子数的模板)的更多相关文章

  1. 牛客小白赛1 F题三视图

    链接:https://www.nowcoder.com/acm/contest/85/F来源:牛客网 题目描述 Etéreo 拿出家里的许多的立方体积木,堆成了一个三维空间中的模型.既然你高考选了技术 ...

  2. 牛客小白赛4J——强迫症

    链接:https://www.nowcoder.com/acm/contest/134/J 来源:牛客网 思路:把数列排序,把每一个重复的元素和最后一个数想加得到新数,在删掉这一元素即为去重的最少步骤 ...

  3. 牛客小白赛4 A 三角形 数学

    链接:https://www.nowcoder.com/acm/contest/134/A来源:牛客网 题目描述 铁子从森林里收集了n根木棍,她开始将它们按顺序的排成一排,从左到右依次为1到n,她回想 ...

  4. 牛客小白赛4 C题

    乘法逆元: 一个数a 乘上 b,在mod之后再还原成本来的数 a 这里就要用到乘法逆元,(a*b)%mod*inv(b,mod)==a ll exgcd(ll a,ll b,ll &x,ll ...

  5. 牛客小白月赛6 G 指纹锁 set的自动排序 模板

    链接:https://www.nowcoder.com/acm/contest/136/G来源:牛客网 题目描述     HA实验有一套非常严密的安全保障体系,在HA实验基地的大门,有一个指纹锁.   ...

  6. 树的最长链-POJ 1985 树的直径(最长链)+牛客小白月赛6-桃花

    求树直径的方法在此转载一下大佬们的分析: 可以随便选择一个点开始进行bfs或者dfs,从而找到离该点最远的那个点(可以证明,离树上任意一点最远的点一定是树的某条直径的两端点之一:树的直径:树上的最长简 ...

  7. 牛客网 牛客小白月赛5 I.区间 (interval)-线段树 or 差分数组?

    牛客小白月赛5 I.区间 (interval) 休闲的时候写的,但是写的心情有点挫,都是完全版线段树,我的一个队友直接就水过去了,为啥我的就超内存呢??? 试了一晚上,找出来了,多初始化了add标记数 ...

  8. 牛客小白月赛8 - E - 诡异数字 数位DP

    牛客小白月赛8 - E - 诡异数字 题意: 求区间中,满足限制条件的数字的个数. 限制条件就是某些数字不能连续出现几次. 思路: 比较裸的数位DP, DP数组开一个dp[len][x][cnt] 表 ...

  9. 牛客小白月赛18 Forsaken给学生分组

    牛客小白月赛18 Forsaken给学生分组 Forsaken给学生分组 链接:https://ac.nowcoder.com/acm/contest/1221/C来源:牛客网 ​ Forsaken有 ...

随机推荐

  1. Ubuntu 下jdk的安装

    因为我ubuntu下需要运行一个java程序,其实是想做一下tc,因为浏览器要运行java插件,那个客户端一直下载不了,我记得我装过的,这个问题后面说.然后我就打算重新安装,通过查找资料,终于解决了手 ...

  2. CountDownLatch实现多线程并发请求

    package com.test; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Dat ...

  3. 最全面的改造Zuul网关为Spring Cloud Gateway(包含Zuul核心实现和Spring Cloud Gateway核心实现)

    前言: 最近开发了Zuul网关的实现和Spring Cloud Gateway实现,对比Spring Cloud Gateway发现后者性能好支持场景也丰富.在高并发或者复杂的分布式下,后者限流和自定 ...

  4. Jenkins 持续集成持续发布使用搭建基础

    一.环境搭建基础 1.持续集成.持续交付.持续部署概念 ①.集成: 是指软件多人研发的部分软件代码整合交付,以便尽早发现个人开发部分的问题:持续集成:强调开发人员提交了新代码之后,立刻进行构建(单元) ...

  5. 浅谈Ceph纠删码

    目  录第1章 引言 1.1 文档说明 1.2 参考文档 第2章 纠删码概念和原理 2.1 概念 2.2 原理 第3章 CEPH纠删码介绍 3.1 CEPH纠删码用途 3.2 CEPH纠删码库 3.3 ...

  6. Java课堂 动手动脑5

    1.了解棋盘打印:利用二维数组输出一个15*15的棋盘,棋盘的原素为“+”,就是输出一个横纵都是15个“+”的二维数组,然后再以坐标形式输入棋子“●”,替换掉原来棋盘里的“+”.再编写代码. 电脑随机 ...

  7. Oracle创建设置查询权限用户

    用户创建的可以参考博客: https://blog.csdn.net/u014427391/article/details/84889023 Oracle授权表权限给用户: 语法:grant [权限名 ...

  8. GBK和UTF-8的区别

    我们这里将以最简单最容易理解的方式来描述GBK和UTF8的区别,以及它们分别是什么.   GBK编码:是指中国的中文字符,其它它包含了简体中文与繁体中文字符,另外还有一种字符“gb2312”,这种字符 ...

  9. JavaWeb——Servlet开发1

    Java Servlet是运行在服务器端上的程序,Servlet是Java Servlet包中的一个接口,能够直接处理和相应客户端的请求,也可以将工作委托给应用的其他类. public interfa ...

  10. Git简易使用教程

    1.Git 安装 2.设置git登录信息 3.git操作命令 4.提交代码的过程中几个命令的顺序 5.git 学习资料. 1.Git 安装 Git 下载地址:https://git-scm.com/d ...