南理第八届校赛同步赛-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,而是在距离广二体育馆一公里远的包间打同步赛(其实就是给写不动题找个理由) 上午身体不舒服,鸽了半天才看题 ...
随机推荐
- 关于C语言内存的一些理解
内存这个大话题 key:心里一定要有内存的逻辑图. 程序是什么? 程序 = 代码 + 数据 代码放在Flash中代码段,可变的数据(全局变量.局部变量)放在内存中. 运行程序的目的是什么? 得到运行结 ...
- rest-framework解析器,url控制,分页,响应器,渲染器,版本控制
解析器 1.json解析器 发一个json格式的post请求.后台打印: request_data---> {'title': '北京折叠'} request.POST---> <Q ...
- GFS浅析
1 . 简介 GFS, Big Table, Map Reduce称为Google的三驾马车,是许多基础服务的基石 GFS于2003年提出,是一个分布式的文件系统,与此前的很多分布式系统的前提假设存在 ...
- linux下jenkins的时区设置问题
https://blog.csdn.net/king_wang10086/article/details/76178711 [root@jenkins ~]# yum install -y ntpda ...
- JS XMLHttpRequesst对象 http post的五种请求状态
记录一下js中对http请求的几种状态,下附代码 readyState 存有 XMLHttpRequest 的状态.从 0 到 4 发生变化. 0: 请求未初始化 1: 服务器连接已建立 2: 请求已 ...
- tailf、tail -f、tail -F三者区别(转)
tail -f 等同于--follow=descriptor,根据文件描述符进行追踪,当文件改名或被删除,追踪停止 tail -F 等同于--follow=name --retry,根 ...
- 给input标签添加默认提示文字
<input name="username" placeholder="请输入用户名" /> placeholder = "提示文字&qu ...
- vue组件star开发基于vue-cli
<template> <div class="stars"> <div v-for="(item,ind) in num" :ke ...
- vue实现双向数据绑定之Object.defineProperty()篇
前言 vue.js中使用ES5的Object.defineProperty()实现数据的双向绑定 Object.defineProperty()原理 Object.defineProperty()可以 ...
- .Net批量插入数据
1. 一般我们普通数据插入是这样的: 现在我们写一个控制台程序用常规办法添加10000条数据. //以下是批量插入数据的办法 //连接字符串 string str = "Server=.;D ...