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 <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <vector>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
const int inf = 1e8;
const double eps = 1e-8;
const double pi = acos(-1.0);
template <class T>
inline bool rd(T &ret) {
    char c; int sgn;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
template <class T>
inline void pt(T x) {
    if (x <0) { putchar('-');x = -x; }
    if(x>9) pt(x/10);
    putchar(x%10+'0');
}
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 1e5;
ll prime[N],primenum;//有primenum个素数 math.h
void PRIME(ll Max_Prime){
	primenum=0;
	prime[primenum++]=2;
	for(ll i=3;i<=Max_Prime;i+=2)
	for(ll j=0;j<primenum;j++)
		if(i%prime[j]==0)break;
		else if(prime[j]>sqrt((double)i) || j==primenum-1)
		{
			prime[primenum++]=i;
			break;
		}
}
ll l, k;
vector<ll>fac;
void factor(ll x){
	fac.clear();
	for(int i = 0; i < primenum && prime[i]*prime[i]<= x; i++)
	{
		if(x%prime[i])continue;
		fac.push_back(prime[i]);
		while(x%prime[i]==0)x/=prime[i];
	}
	if(x!=1)fac.push_back(x);
//	cout<<x<<" " ;puts("factor:");	for(int i = 0; i < fac.size(); i++){
//		pt(fac[i]); puts("**");
//	}
}
ll solve(ll x){//计算与x有2个及以上的因子个数
	if(x<=0)return 0;
	if(x == 1)return 1;
	ll sum = 0, siz = (int)fac.size();
	for(int i = 1; i < (1<<siz); i++)
	{
		ll lcm = 1, one = 0;
		for(int j = 0; j < siz; j++)
			if(i & (1<<j))
			{
				lcm *= fac[j];
				one++;
			}
		if(one&1)
			sum += x/lcm;
		else sum -= x/lcm;
	}
	return x-sum;
}
int main(){
	PRIME(1e5+10);
	while(cin>>l>>k){
		factor(l);
		ll L = 1, R = 1e18, ans = 1;
		while(L <= R){
			ll mid = (L+R)>>1;
			ll ok = solve(mid);
			if(ok<k)L = mid+1;
			else {
				ans = mid;
				R = mid-1;
			}
		}
		pt(ans); puts("");
	}
    return 0;
}

solve(x) 实现:

时间: 2024-12-20 01:18:05

POJ 2773 Happy 2006 二分+容斥(入门的相关文章

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<bitse

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

[二分+容斥原理] poj 2773 Happy 2006

题目链接: http://poj.org/problem?id=2773 Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9131   Accepted: 3073 Description Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1.

POJ 2773 Happy 2006

Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9170   Accepted: 3092 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 al

hdu1796:容斥入门题

简单的容斥入门题.. 容斥基本的公式早就知道了,但是一直不会写. 下午看到艾神在群里说的“会枚举二进制数就会容斥”,后来发现还真是这样.. 然后直接贴代码了 #include <iostream> #include <stdio.h> #include<string.h> #include<algorithm> #include<string> #include<ctype.h> using namespace std; long l

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

poj 2773 Happy 2006(欧拉函数应用)

http://poj.org/problem?id=2773 题意:输入n,k,求与n不互素的第k个数,k可能大于n. 思路:以n=6为例,与6互素的数有一定规律.{1,5},{7,12},{13,18}......,发现在[1,n],[n+1,n*2]......[m*n+1,(m+1)*n]区间内素数个数相同,且对应位置的数都相差n的整数倍.因此只要求出[1,n]内的与n互素的数即可.这个过程没必要一个一个枚举,可以用欧拉函数解决.因为欧拉函数已经求出了n的所有质因子,与n不互素的数都与n有

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 题目大意: 给你两个整数N和K,找到第k个与N互素的数(互素的数从小到大排列),其中 (1 <= m <= 1000000,1 <= K <= 100000000 ). 解题思路: K很大,直接从小到大枚举找出不现实,只能二分答案.二分枚举[1,INF]范围内所有的数x, 找到1~x范围内与N互素的数个数,如果等于K,则就是结果. 然后考虑1~x范围内与N互素的数个数 = x - 1~x范围内与N不互素的数个