容斥原理解决某个区间[1,n]闭区间与m互质数数量问题
首先贴出代码(闭区间[1,n]范围内和m互质的数)
代码:
int solve(II n,II m){
vector<II>p;
for(II i=;i*i<=m;i++){
if(m%i==){
p.push_back(i);
while(m%i==) m/=i;
}
}
if(m>) p.push_back(m);
II sz=p.size();
LL sum=;
for(II i=;i<(<<sz);i++){
II ct=;
LL mul=;
for(II j=;j<sz;j++){
if(i&(<<j)){
ct++;
mul*=p[j];
}
}
if(ct&) sum+=n/mul;
else sum-=n/mul;
}
return n-sum;
}
这里解释一下原理:首先假设m有x个不同的质因子,那么可以组成的因子数就是2^x-1种,然后10^18以内所有的数的质因子个数不会超过15个,所以2^15次方暴力枚举所有情况这个复杂度还是可取的。我们假设p1,p2,p3都是m的质因子,假设当前枚举的因子是p1*p2*p3那么n以内可以整除p1*p2*p3的数量就是n/(p1*p2*p3),但是这里考虑到一个会重复问题就是拥有奇数个质因数的因子的在n以内可以整除的数量已经包含了偶数个数量,但是偶数个的并不包含奇数个的,所以我们枚举的时候需要奇加偶减,这样我们算出来的ans是n以内和m不互质的数的数量,那么和m互质的数量就是n-ans。
贴上一些可以用这个方法解决的练习题:
HDU1695:这个题好像正解使用什么莫比乌斯反演,题目的意思是求[1,a],[1,b]有多少对数GCD(x,y)==k,但是(x,y)和(y,x)算一对,有一个定理如果GCD(x,y)==k ,则GCD(x/k,y/k)==1那么现在问题转化为求[1,a/k],[1,b/k]以内互质的数有多少对,现在我们要取minn=min(a/k,b/k),我们可以先求minn的欧拉函数的前缀和,然后再求minn+1到max(a/k,b/k)的数在[1,max(a/k.b/k)]以内所有与它互质的数的数量,然后把所有的加起来就可以了。
代码:
//Author: xiaowuga
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define MAX INT_MAX
#define mem(s,ch) memset(s,ch,sizeof(s))
const long long N=;
const long long mod=1e9+;
typedef long long LL;
typedef int II;
typedef unsigned long long ull;
#define nc cout<<"nc"<<endl
#define endl "\n"
vector<LL>Euler;
void init_Euler(II n){
Euler.resize(n+);
Euler[]=;
Euler[]=;
for(LL i=;i<n;i++) Euler[i]=i;
for(LL i=;i<n;i++){
if(Euler[i]==i){
for(LL j=i;j<n;j+=i)
Euler[j]=Euler[j]/i*(i-);//先进行除法防止溢出
}
}
for(II i=;i<n;i++){
Euler[i]+=Euler[i-];
}
}
int solve(II n,II m){
vector<II>p;
for(II i=;i*i<=m;i++){
if(m%i==){
p.push_back(i);
while(m%i==) m/=i;
}
}
if(m>) p.push_back(m);
II sz=p.size();
LL sum=;
for(II i=;i<(<<sz);i++){
II ct=;
LL mul=;
for(II j=;j<sz;j++){
if(i&(<<j)){
ct++;
mul*=p[j];
}
}
if(ct&) sum+=n/mul;
else sum-=n/mul;
}
return n-sum;
}
int main() {
ios::sync_with_stdio(false);cin.tie();
II a,b,c,d,k;
II T,ca=;
init_Euler(+);
cin>>T;
while(T--){
cin>>a>>b>>c>>d>>k;
if(k==||k>b||k>d){
cout<<"Case "<<++ca<<": "<<<<endl;
continue;
}
if(b>d) swap(b,d);
b/=k;d/=k;
LL ans=Euler[b];
for(II i=b+;i<=d;i++){
ans+=solve(b,i);
}
cout<<"Case "<<++ca<<": "<<ans<<endl;
}
return ;
}
POJ2773:这个题求第n个与k互质的数。
1.一个简单的思路就是如果[1,k]中有x个与k互质的数,那么[k+1,2*k]中也有x个,每个k个一个循环都会出现x个数与k互质,而且加入y<k且y与k互质,则t*k+y也与k互质。那么我们第一个方法可以暴力算出比k小的数里面所有与k互质的数都是多少复杂度是klog(k),然后看一下n是k第几轮循环里面。然后直接确定这个数多少。
2.二分+验证的思想,首先一个数越大,那么他包含的与k互质的数一定越多对吧?这个性质不就是单调性吗?任何满足单调性的问题我们都可以用二分来解决,所以我们可以用二分,加验证的思想找到和第n个k互质的数是多少
代码:
//Author: xiaowuga
#include<iostream>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define MAX INT_MAX
#define mem(s,ch) memset(s,ch,sizeof(s))
const long long N=;
const long long mod=1e9+;
typedef long long LL;
typedef int II;
typedef unsigned long long ull;
#define nc cout<<"nc"<<endl
#define endl "\n"
LL solve(II r,LL n){
vector<int>p;
for(II i=;i*i<=r;i++){
if(r%i==){
p.push_back(i);
while(r%i==) r/=i;
}
}
if(r>) p.push_back(r);
LL sum=;
for(LL i=;i<(<<p.size());i++){
LL d=,ct=;
for(II j=;j<p.size();j++){
if(i&(<<j)){
ct++;
d*=p[j];
}
}
if(ct%) sum+=n/d;
else sum-=n/d;
}
return n-sum;
}
int main() {
ios::sync_with_stdio(false);cin.tie();
II n,k;
while(cin>>n>>k){
LL l=,r=inf*;
LL ans=;
while(l<r){
LL m=l+(r-l)/;
LL t=solve(n,m);
if(t>=k){
if(t==k) ans=m;
r=m;
}
else{
l=m+;
}
}
cout<<ans<<endl;
}
return ;
}
容斥原理解决某个区间[1,n]闭区间与m互质数数量问题的更多相关文章
- paip. 解决php 以及 python 连接access无效的参数量。参数不足,期待是 1”的错误
paip. 解决php 以及 python 连接access无效的参数量.参数不足,期待是 1"的错误 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源 ...
- HDU 3709 Balanced Number 求区间内的满足是否平衡的数量 (数位dp)
平衡数的定义是指,以某位作为支点,此位的左面(数字 * 距离)之和 与右边相等,距离是指某位到支点的距离; 题意:求区间内满足平衡数的数量 : 分析:很好这又是常见的数位dp , 不过不同的是我们这次 ...
- 2017乌鲁木齐区域赛K(容斥原理【求指定区间内与n互素的数的个数】)
#include<bits/stdc++.h>using namespace std;const long long mod = 998244353;typedef const long ...
- 贪心算法----区间选点问题(POJ1201)
题目: 题目的大致意思是,给定n个闭区间,并且这个闭区间上的点都是整数,现在要求你使用最少的点来覆盖这些区间并且每个区间的覆盖的点的数量满足输入的要求点覆盖区间的数量. 输入: 第一行输入n,代表n个 ...
- BZOJ 3226: [Sdoi2008]校门外的区间
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3226 题意:初始集合S为空.模拟四种集合操作:集合并.交.差.补集并. 思路:区间 ...
- [kuangbin带你飞]专题二十二 区间DP
ID Origin Title 17 / 60 Problem A ZOJ 3537 Cake 54 / 105 Problem B LightOJ 1422 Hallowee ...
- POJ 2773 Happy 2006#素数筛选+容斥原理+二分
http://poj.org/problem?id=2773 说实话这道题..一点都不Happy好吗 似乎还可以用欧拉函数来解这道题,但正好刚学了容斥原理和二分,就用这个解法吧. 题解:要求输出[1, ...
- 线段树(区间树)之区间染色和4n推导过程
前言 线段树(区间树)是什么呢?有了二叉树.二分搜索树,线段树又是干什么的呢?最经典的线段树问题:区间染色:正如它的名字而言,主要解决区间的问题 一.线段树说明 1.什么是线段树? 线段树首先是二叉树 ...
- HDU1695:GCD(容斥原理+欧拉函数+质因数分解)好题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题目解析: Given 5 integers: a, b, c, d, k, you're to ...
随机推荐
- SSH远程登录其他机器
常用格式:ssh [-l login_name] [-p port] [user@]hostname更详细的可以用ssh -h查看. 不指定用户: ssh 192.168.0.11 指定用户: ssh ...
- nodejs基础 -- NPM 使用介绍
npm:是nodejs的包管理工具,随NodeJS一起安装的,能解决NodeJS代码部署上的很多问题,如: 1.允许用户从NPM服务器下载别人编写的第三方包到本地使用. 2.允许用户从NPM服务器下载 ...
- [精]Odoo 8.0深入浅出开发教程-模块开发基础
參考资料点击这里. 构建Odoo模块 模块组成 业务对象 业务对象声明为Python类, 由Odoo自己主动加载. 数据文件 XML或CSV文件格式, 在当中声明了元数据(视图或工作流).配置数据(模 ...
- 记录一下我的GDB配置
一:为了更好的在GDB中显示STL容器.我们首先要下载一个python脚本 PS:要确定你所安装的GDB能够运行python脚本 cd ~ mkdir .gdb cd .gdb svn co svn: ...
- Linux /proc/loadavg(平均负载)
from : http://hi.baidu.com/mengyun8/blog/item/bd424531451b98e71a4cffc0.html 一.什么是系统平均负载(Load average ...
- 【python】多进程多线程
import threading import multiprocessing class MultiThread(threading.Thread): def __init__(self,func, ...
- 继承MonoBehaviour类的优缺点和相关报错
Unity3D文档里虽然说所有脚本继承MonoBehaviour类,但如果你想自定义类,就可以不用继承MonoBehaviour,但是这个类只能调用其中的方法和属性,无法拖到场景的物体中使用. 所有从 ...
- vs2013\2015-UML
1.UML简介Unified Modeling Language (UML)又称统一建模语言或标准建模语言. 简单说就是以图形方式表现模型,根据不同模型进行分类,在UML 2.0中有13种图,以下是他 ...
- Cocos2d-x3.0终于版Mac以及Win系统相关环境部署
因个人原因此博客停止更新,其它更新博文将在该博客继续更新. http://blog.csdn.net/xiaohan_aimti/article/details/24653831 就在前几天,2014 ...
- java中定义一个CloneUtil 工具类
其实所有的java对象都可以具备克隆能力,只是因为在基础类Object中被设定成了一个保留方法(protected),要想真正拥有克隆的能力, 就需要实现Cloneable接口,重写clone方法.通 ...