POJ 2773 Happy 2006(求第k个与m互素的数)
来源:互联网 发布:淘宝药店旗舰店靠谱吗 编辑:程序博客网 时间:2024/05/29 04:54
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 all relatively prime to 2006.
2006 1
2006 2
1
3
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 all relatively prime to 2006.
Now your job is easy: for the given integer m, find the K-th element which is relatively prime to m when these elements are sorted in ascending order.
The input contains multiple test cases. For each test case, it contains two integers m (1 <= m <= 1000000), K (1 <= K <= 100000000).
Output the K-th element in a single line.
2006 1
2006 2
2006 3
1
3
5
原理是欧几里得算法的变形:gcd(b×t+a,b)=gcd(a,b)(t为任意整数),
则如果a与b互素,则b×t+a与b也一定互素,如果a与b不互素,则b×t+a与b也一定不互素
故与m互素的数对m取模具有周期性。
例如m=9,小于m且和m互素的数有6个:1、2、4、5、7、8.
大于m且和m互素的数具有周期性:10(=9*1+1)、11(=9*1+2)、13(=9*1+4)...17(=9*1+8)、19(=9*2+1)...
还有值得注意的是:在计算小于m且和m互素的数时,如果用gcd(m,i)==1依次判断时间会比较长(2000+ms),如下:
#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cctype>#include<cmath>#include<algorithm>#include<string>#include<stack>#include<ctime>#include<vector>#include<map>#include<climits>using namespace std;const int M = 1000005;typedef long long LL;int p[M];int gcd(int a,int b){ int t; while(b!=0) { t=a%b; a=b; b=t; } return a;}int main(){ //freopen("in.txt","r",stdin); int m,k; while(~scanf("%d%d",&m,&k)){ int j=1; for(int i=1;i<=m;i++) if(gcd(m,i)==1) p[j++]=i; j--; if(k%j) printf("%d\n",p[k%j]+k/j*m); else printf("%d\n",p[j]+(k/j-1)*m); } return 0;}
用以下这种筛法会省时得多(100+ms)
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#define LL long long#define mset(x,y) memset(x,y,sizeof(x))using namespace std;bool F[1100000];//F[i]=1表示i与m有公约数,F[i]=0表示i与m互素int p[1100000];//p[i]表示第i个与m互素的数int main(){ int m,k; //while (scanf("%d%d",&m,&k)!=EOF) while (cin>>m>>k) { mset(F,0); for (int i=2;i<=m;i++) { if (!F[i] && m%i==0) { int j=i*2; F[i]=1; while (j<m) { F[j]=1; j+=i; } } } p[0]=0; F[1]=0; for (int i=1;i<=m;i++) { if (!F[i]) { p[0]++; p[p[0]]=i; } }/*后面都一样*/ int o=p[0]; int x,y; x=k/o; y=k%o; LL ans; if (y==0) {y=p[0];x--;} ans=x*m+p[y]; cout<<ans<<endl; } return 0;}
0 0
- POJ 2773 Happy 2006(求第k个与m互素的数)
- poj 2773 Happy 2006(求第k个与n互质的数)
- POJ 2773 Happy 2006(求第k个和m互素的数/欧拉函数)
- poj 2773 容斥原理求第k个与m互质的数
- POJ 2773:Happy 2006 - 第k大与n互素的数
- poj2773求第K个与m互质的数
- (Relax 1.15)POJ 2773 Happy 2006(欧拉函数的应用:求与n互质的第k个数)
- 求m个区间中第k小的数
- BOJ 2773 第K个与m互质的数
- nyoj 762第k个互质数 poj 2773Happy 2006
- 求第K个最大的数
- Home_W的超级数学题(第k个和m互素的数
- 求数组中第K个大小的数
- poj 2773 容斥原理+二分(求与n的第k互质数)
- boj_420_求第k个最小数
- 求二叉树第m层上的第K个结点的值
- POJ 2761-Feed the dogs(划分树)求区间内第k小的数
- poj 2104(划分树 求第k大的数)
- 二维运动物体坐标提取软件
- C++ primer 5th 习题之4.21
- iOS 基本编码格式转化
- node.js 学习笔记001 :Hello,world !
- 分糖
- POJ 2773 Happy 2006(求第k个与m互素的数)
- Python字典(Dictionary)
- 高僧斗法
- GRAY
- js 时间计算
- 模板--判断两线段是否相交
- Swift-AES之加密解密
- 分析C语言的声明的优先级
- 利用FormData,进行Ajax请求并上传文件