poj2773 Happy 2006(二分+容斥)

题目链接:点这里!!!!

题意:

给你两个整数m(1<=m<=1e6),k(1<=k<=1e8)。求第k个与m互质的数是多少。

题解:

直接二分+容斥。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cstdlib>
#include<cmath>
#define PI 2*asin(1.0)
#define LL long long
#define pb push_back
#define pa pair<int,int>
#define clr(a,b) memset(a,b,sizeof(a))
#define lson lr<<1,l,mid
#define rson lr<<1|1,mid+1,r
#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)
#define key_value ch[ch[root][1]][0]C:\Program Files\Git\bin
const LL  MOD = 1E9+7;
const LL N = 1e3+15;
const int maxn = 5e5+15;
const int letter = 130;
const LL INF = 1e18;
const double pi=acos(-1.0);
const double eps=1e-10;
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int x,k;
int vis[N],prime[N],cnt=0;
int ps[30],num;
void init(){
    vis[1]=1;
    for(int i=2;i<N;i++){
        if(!vis[i]) prime[++cnt]=i;
        for(int j=1;j<=cnt&&i*prime[j]<N;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
LL check(LL x){
    ///[1,x]
    LL sum=x,ans=1,res=0;
    int cc=0;
    for(int i=1;i<(1<<num);i++){
        cc=0;
        LL ans=1;
        for(int j=0;j<num;j++){
            if(i&(1<<j)){
                cc++;
                ans*=1ll*ps[j];
            }
        }
        if(cc%2) res+=x/ans;
        else res-=x/ans;
    }
    return sum-res;
}
int main(){
    init();
    while(scanf("%d%d",&x,&k)!=EOF){
        num=0;
        for(int i=1;i<=cnt;i++){
            if(x%prime[i]==0){
                while(x%prime[i]==0) x/=prime[i];
                ps[num++]=prime[i];
            }
        }
        if(x!=1) ps[num++]=x;
        LL l=1,r=INF,mid;
        LL flag;
        while(l<r){
            mid=(l+r)/2;
            flag=check(mid);
            if(flag<k) l=mid+1;
            else r=mid;
        }
        printf("%I64d\n",r);
    }
    return 0;
}
/*
12 4
*/
时间: 2024-08-28 20:52:55

poj2773 Happy 2006(二分+容斥)的相关文章

POJ 2773 Happy 2006 二分+容斥(入门

题目链接:点击打开链接 题意: 输入n ,k 求与n互质的第k个数(这个数可能>n) 思路: solve(mid)表示[1,mid]中有多少个和n互质,然后二分一下最小的mid 使得互质个数==k solve(x) 实现: 与n互质的个数=所有数-与n不互质的数=所有数-(与n有一个因子-与n有2个因子的+与n有3个因子的) 状压n的因子个数,然后根据上面的公式容斥得到. #include <stdio.h> #include <iostream> #include <

codeforces B. Friends and Presents(二分+容斥)

题意:从1....v这些数中找到c1个数不能被x整除,c2个数不能被y整除! 并且这c1个数和这c2个数没有相同的!给定c1, c2, x, y, 求最小的v的值! 思路: 二分+容斥,二分找到v的值,那么s1 = v/x是能被x整除的个数 s2 = v/y是能被y整除数的个数,s3 = v/lcm(x, y)是能被x,y的最小公倍数 整除的个数! 那么 v-s1>=c1 && v-s2>=c2 && v-s3>=c1+c2就是二分的条件! 1 #incl

【二分+容斥+莫比乌斯反演】BZOJ2440 完全平方数

Description 求第k个没有完全平方因子的数,k<=1e9. Solution 这其实就是要求第k个µ[i](莫比乌斯函数)不为0的数. 然而k太大数组开不下来是吧,于是这么处理. 二分答案x,问题转化为求[1,x]间有多少个没有完全平方因子的数. 容斥,加上全部,减去一个质数的平方的倍数个数,加上两个质数乘积的平方的倍数个数... 然后发现,每个数的系数就是µ 这也说明了莫比乌斯的原理就是容斥,µ函数就是容斥系数 具体来说,对于每一个i<=sqrt(x),对于ans的贡献就是µ[i]

第k个互质数(二分 + 容斥)

描述两个数的a,b的gcd为1,即a,b互质,现在给你一个数m,你知道与它互质的第k个数是多少吗?与m互质的数按照升序排列. 输入 输入m ,k (1<=m<=1000000;1<=k<=100000000) 输出 输出第k个数. 样例输入 10 1 10 2 10 3 样例输出 1 3 7 首先对m进行质因数分解,求出m有哪些质因数,然后用容斥求[1, mid]内与m互质的数有多少个. 判断的时候,[1,mid]之间与m互质的数的数量 = mid - (包含一个质因子的数的个数)

Codeforces 920G(二分+容斥)

题意: 定义F(x,p)表示的是一个数列{y},其中gcd(y,p)=1且y>x 给出x,p,k,求出F(x,p)的第k项 x,p,k<=10^6 分析: 很容易想到先二分,再做差 然后问题就变成了[1,x]内有多少个数是和p互质的 我们可以先将p质因数分解,然后用这些数组合去在[1,x]容斥就行了 1 long long cal(long long x) 2 { 3 int n=f.size(); 4 long long ans=0; 5 for(int i=0;i<(1<<

Codeforces 483B - Friends and Presents(二分+容斥)

483B - Friends and Presents 思路:这个博客写的不错:http://www.cnblogs.com/windysai/p/4058235.html 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset((a),(b),sizeof(a)) const ll INF=1e18; ll c1,c2,

POJ 2773 Happy 2006 (分解质因数+容斥+二分 或 欧几里德算法应用)

Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10309   Accepted: 3566 Description Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1. For instance, 1, 3, 5, 7, 9...are a

POJ 2773 Happy 2006 (二分答案+容斥)

题目链接:http://poj.org/problem?id=2773 题意: 求第k个与m互质的数: 分析: 很明显随着数的增大与m互质的数就越多,因此我们可以二分答案, 中间需要用到容斥原理求[1,mid]内与m互质的数的个数: 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <vector> using namespace std; const int ma

BZOJ2440(全然平方数)二分+莫比乌斯容斥

题意:全然平方数是指含有平方数因子的数.求第ki个非全然平方数. 解法:比較明显的二分,getsum(int middle)求1-middle有多少个非全然平方数,然后二分.求1-middle的非全然平方数个数能够用总数减掉全然平方数个数.计算全然平方数的个数用容斥: 首先加上n/(2*2)+n/(3*3)+n/(5*5)+n/(7*7)...+...然后减掉出现两次的,然后加上三次的...奇加偶减.这就是mou的原型,用mou数组计算非常easy: 代码: /*****************