Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 10751 | Accepted: 3744 |
Description
Input
Output
Sample Input
2006 1 2006 2 2006 3
Sample Output
1 3 5
题意:求出与m互素的第k大的数
首先,介绍一个定理:若a与b不互素,则,tb+a与b也不互素,若a与b互素,则tb+a与b互素。所以,这个题目可以先求出m以内的与m互素的数,大于m的可以用l*m+a求出,其中a为小于m的与m互素的数,l为循环次数。
用欧拉函数求出循环长度,同时对m以内的素数(即大于m的素数%m的余数)进行标记
(吐槽一下,昨天用sublime打欧拉的模板打错了,在dev上改了过来,sublime上保存的依然是错的,今天拿着错误的模板wa了好多发……也是醉了)
#include <stdio.h> #include<string.h> long long m,k; int pan[1000008]; long long phi(long long n) { long long m=n; long long i,cnt,j; cnt=n; for(i=2;i*i<=n;i++) { if(n%i==0) { for(j=i;j<=m;j=j+i)pan[j]=1; cnt=cnt-cnt/i; while(n%i==0)n=n/i; } } //printf("n:%lld\n",n); if(n>1){for(j=n;j<=m;j=j+n)pan[j]=1;cnt=cnt-cnt/n;} return cnt; } int main(int argc, char const *argv[]) { long long i,n; while(~scanf("%lld%lld",&m,&k)) { if(m==1){printf("%lld\n",k);continue;} memset(pan,0,sizeof(pan)); long long f=phi(m); // for(i=1;i<=m;i++)printf("%lld:%lld\n",i,pan[i]); long long t=(k-1)/f; long long p=(k-1)%f+1; long long cnt=0; for(i=1;i<=1000001;i++) { if(pan[i]==0)cnt++; if(cnt==p){cnt=i;break;} } long long sum=cnt+t*m; printf("%lld\n",sum); } return 0; }