POJ2773 Happy 2006【容斥原理】
2024-09-30 19:40:40
题目链接:
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不互素的数个数
1~x范围内与N不互素的数个数用简单的容斥定理来求就可以。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL __int64
using namespace std;
const LL INF = 0xfffffff0; int Prime[1000010],ct,N; void Divide()
{
ct = 0;
int n = N;
for(int i = 2; i <= sqrt(n*1.0); ++i)
{
if(n % i == 0)
{
Prime[ct++] = i;
while(n % i == 0)
n /= i;
}
}
if(n != 1)
Prime[ct++] = n;
} LL Solve(int n)
{
LL ans = 0;
for(int i = 1; i < (1 << ct); ++i)
{
LL odd = 0;
LL tmp = 1;
for(int j = 0; j < ct; ++j)
{
if((1 << j) & i)
{
odd++;
tmp *= Prime[j];
}
}
if(odd & 1)
ans += n/tmp;
else
ans -= n/tmp;
}
return n - ans;
} int main()
{
int K;
while(~scanf("%d%d",&N,&K))
{
Divide();
LL Left = 1, Right = INF, Mid, tmp;
while(Left < Right) //二分答案
{
Mid = (Left + Right) >> 1;
tmp = Solve(Mid);
if(tmp >= K)
Right = Mid;
else
Left = Mid + 1;
}
printf("%I64d\n",Left); } return 0;
}
最新文章
- Oracle环境变量NLS_LANG
- http://jingyan.baidu.com/article/e4511cf33479812b855eaf67.html
- 使用phpize安装php模块
- C++开源小贱鸡(simsimi api)
- javascript----bug
- nginx编译配置
- 邮件发送 emailsend .net开发
- Angularjs 滚动条控制
- webstorm11.0.3连接ftp
- Elasticsearch创建索引和映射结构详解
- Android-AndroidManifest.xml默认启动的Activity(探索篇01)
- Lucene.net 全文检索数据库
- 让 IE6, 7和 8支持CSS3的HTC文件补丁
- I/O Completion Ports
- LNMP-day2-进阶
- Codeforces 806 D.Prishable Roads
- Macro definition of snprintf conflicts with Standard Library function declaration
- fatal error C1083: 无法打开包括文件:“stdint.h”: No such file or directory
- 「新手向」koa2从起步到填坑
- kuangbin专题十六 KMP&;&;扩展KMP HDU4300 Clairewd’s message