南理第八届校赛同步赛-C count_prime//容斥原理
大致思路就是先求出n的质因数假设是a1-an,然后在1-a的区间里面查找至少能整除{a1,a2...an}中一个元素的数有多少个,对1-b也做相同的处理,而找出来的元素肯定是与n不互质的,那么把区间的长度减去元素的个数就是那个区间里面与n互质的数的个数了,然后1-b的减去1-(a-1)的就是答案了。
而在1-a的区间里面查找至少能整除{a1,a2...an}中一个元素的数有多少个,这里就要用到容斥原理了。
首先来看容斥原理
在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。
就比如质因数有2,3 然后1-10里面能整除2的有2,4,6,8,10;能整除3的有3,6,9;把这个看作成集合A,集合B,|A∩B|=1,|A|=5,|B|=3,|A∪B|=|A|+|B|-|A∩B|;
将这个公式推广到n个集合
回到题目,考虑质因子{a1,a2,a3..an},那么在[1-r]有多少个数能整除ai,答案就是[r/ai],但是单纯的把答案加上去肯定是错的(有些数可能被好几个质因子整除),这个时候就用到容斥原理来解决。
假设有m个质因子,那么就有2^m-1种情况(lcm(...),中间填入数字,每个数字都有两种选择,填还是不填,但不能全部都不填对吧);
附上模板
int solve (ll n, ll r)
{ vector<ll> p;
p.clear();
for (int i=; i*i<=n; ++i)
if (n % i == )
{
p.push_back (i);
while (n % i == )
n /= i;
}
if (n > )
p.push_back (n);
//分解质因数
ll sum = ;
ll cur;
ll mult = ;
ll bits = ;
ll s=<<p.size();
for (ll msk=; msk<s; msk++)
{ mult = ;
bits = ;
for (int i=; i<p.size(); ++i)
if (msk & (<<i))
{
bits++;
mult *= p[i]; }
cur = r / mult;
if (bits % == )
sum += cur;
else
sum -= cur; }
//printf("%lld\n",sum);
return r - sum;//1-r与n互质的数的个数 }
我把模板里面的位运算解释一下吧,p.size()代表n的质因数有多少个,而1<<p.size()就是2^(p.size()),mult表示某几个质因数的最小公倍数,bits表示集合的个数,用msk把1->p.size()-1里面所有的数用二进制表示出来,而if(a&b)表示a和b的二进制表示有没有相同的一位都为1,如果有就为真,没有就为假,现在假如有一个数30,那么它的质因数有2,3,5,那么一共有001,010,011,100,101,110,111,这七种情况,在里面的第二个循环其实就是为了读取msk的二进制有哪几位是1,因为二进制把所有的情况都包括了,就比如001,001&001=1,其他的都为假,这个时候就读到了|A1|这种情况,即2,里面的循环1<<i,只能得到001,010,100这几个数,010&010=1,其他的都为假,这个时候就读到了|A2|这种情况,即3,011&001=1,011&010=1,这个时候就读取到了|A1∩A2|的情况,即2,3的最小公倍数即6,而由于容斥原理当里面的集合有偶数个的时候是要减去这个集合里面元素的数量的,所以这个时候就知道了|A1|+|A2|-|A1∩A2|,
100&100=1,这个时候读到了|A3|,
101&001=1,101&100=1,这个时候读到了|A1∩A3|,
110&100=1,110&010=1,这个时候读到了|A2∩A3|,
111&001=1,111&010=1,111&100=1,这个时候读到了|A1∩A2∩A3|,
到这个时候所有的情况已经全部都读取完毕了,然后按照在[1-r]有多少个数能整除ai,答案就是[r/ai]这种性质,就能求出每个集合里面元素的数量,然后按照容斥原理的公式相加减就好了。
那么答案就是套模板了
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
vector<ll> p;
int solve (ll n, ll r)
{ p.clear();
for (int i=; i*i<=n; ++i)
if (n % i == )
{
p.push_back (i);
while (n % i == )
n /= i;
}
if (n > )
p.push_back (n);
//分解质因数
ll sum = ;
ll cur;
ll mult = ;
ll bits = ;
ll s=<<p.size();
for (ll msk=; msk<s; msk++)
{ mult = ;
bits = ;
for (int i=; i<p.size(); ++i)
if (msk & (<<i))
{
bits++;
mult *= p[i]; }
cur = r / mult;
if (bits % == )
sum += cur;
else
sum -= cur; }
//printf("%lld\n",sum);
return r - sum;//1-r与n互质的数的个数 }
int main()
{
ll a,b,n;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld %lld %lld",&a,&b,&n);
ll r=solve(n,b);
ll l=solve(n,a-);
printf("%lld\n",r-l); }
}
南理第八届校赛同步赛-C count_prime//容斥原理的更多相关文章
- 南理第八届校赛同步赛-F sequence//贪心算法&二分查找优化
题目大意:求一个序列中不严格单调递增的子序列的最小数目(子序列之间没有交叉). 这题证明贪心法可行的时候,可以发现和求最长递减子序列的长度是同一个方法,只是思考的角度不同,具体证明并不是很清楚,这里就 ...
- 哈尔滨理工大学软件与微电子学院第八届程序设计竞赛同步赛(高年级) Solution
A: Solved. 分别处理出每个%7后余数的数字个数,再组合一下 #include <bits/stdc++.h> using namespace std; #define ll lo ...
- NOIP2013,复赛及同步赛,报名及比赛,专题页面
本通知的对象仅仅是福州第十九中学的学生 所有参加复赛以及同步赛的选手,请务必要仔细阅读:<关于CCF NOIP2013复赛有关事宜的通知>,里面有比赛的时间.地点.以及比赛费用的说明. 参 ...
- 山东省ACM多校联盟省赛个人训练第六场 poj 3335 D Rotating Scoreboard
山东省ACM多校联盟省赛个人训练第六场 D Rotating Scoreboard https://vjudge.net/problem/POJ-3335 时间限制:C/C++ 1秒,其他语言2秒 空 ...
- Minieye杯第十五届华中科技大学程序设计邀请赛现场同步赛 I Matrix Again
Minieye杯第十五届华中科技大学程序设计邀请赛现场同步赛 I Matrix Again https://ac.nowcoder.com/acm/contest/700/I 时间限制:C/C++ 1 ...
- NOI Day1线上同步赛梦游记
Preface 第一次体验NOI,虽然不是正式选手,但是打打同步赛还是挺涨姿势的,也算是体验了一把. Day1很爆炸,一方面是NOI题目的难度高于自身的水平,另一方面也出现了比较大的失误,T1一个数组 ...
- NOI 2018网络同步赛(游记?)
刚中考完那段时间比较无聊,报名了一个同步赛,报完名才发现成绩单是要挂到网上的,而且因为报的早给了一个很靠前的考号...那布星啊,赶紧学点东西,于是在一周内学了网络流,Treap以及一些数论. Day1 ...
- 10.17(山东多校联合模拟赛 day1)
山东多校联合模拟赛 day1 题不难 rect [问题描述] 给出圆周上的 N 个点, 请你计算出以这些点中的任意四个为四个角,能构成多少个矩形. 点的坐标是这样描述的, 给定一个数组 v[1..N] ...
- 【NOI 2019】同步赛 / 题解 / 感想
非常颓写不动题怎么办…… 写下这篇博客警示自己吧…… 游记 7.16 我并不在广二参加 NOI,而是在距离广二体育馆一公里远的包间打同步赛(其实就是给写不动题找个理由) 上午身体不舒服,鸽了半天才看题 ...
随机推荐
- p9半幺群
如何不理解划红线的地方?第二个划红线地方,请举一个例子 1.0不是幺元 2.f(1)=2, f(2)=1, f(3)=3, g(1)=2, g(2)=3, g(3)=1 fg不等于gf
- 架构 规则引擎 quartz
通向架构师的道路(第五天)之tomcat集群-群猫乱舞-云栖社区-阿里云https://yq.aliyun.com/articles/259343 商业规则引擎和开源规则引擎的测试对比 - qq_39 ...
- 五、es6 Set
一.特点 1.是一个构造函数 2.类数组,元素唯一.没有重复 二.new Set(); 二.构造函数接受数组将数组转换成Set数据结构,[...new Set(1,3)],转化成对象: console ...
- React Native之TextInput的介绍与使用(富文本封装与使用实例,常用输入框封装与使用实例)
React Native之TextInput的介绍与使用(富文本封装与使用实例,常用输入框封装与使用实例) TextInput组件介绍 TextInput是一个允许用户在应用中通过键盘输入文本的基本组 ...
- yolo buffer is too small for requested array
yolo.cfg 与 yolo.weights 版本一定要对应, darknet链接 https://github.com/pjreddie/darknet 下载后在cfg文件夹下找到yolov2的配 ...
- Mac上通过iterm 上传文件到服务器
.安装 brew install lrzsz #这里以homebrew方式安装12.脚本 拉取 https://github.com/mmastrac/iterm2-zmodem 两个sh文件,将他们 ...
- Windows 下面 redis 发布为服务的官方方法
除了 NSSM 之外 另外一种方式 感觉还是很好用的 redis-server --service-install redis.windows.conf --loglevel verbose 感觉也可 ...
- Docker 给 故障停掉的 container 增加 restart 参数
操作过程见图: 执行的命令比较简单: docker container update --restart=always containername 即可.
- 【转帖】理解 Linux 的虚拟内存
理解 Linux 的虚拟内存 https://www.cnblogs.com/zhenbianshu/p/10300769.html 段页式内存 文章了里面讲了 页表 没讲段表 记得最开始的时候 学习 ...
- Spring是如何校验XML的
首先来看下xml的一些概念: xml的schema里有namespace,可以给它起个别名.比如常见的spring的namespace: xmlns:mvc="http://www.spri ...