首页 > 代码库 > POJ 2773
POJ 2773
不经意看见dis后的“mod”一词后,瞬间有了思路,点进去看,却发现别人想的和我的不一样——!
我是这样想的,利用的是剩余系+欧几里德带余除法的性质。
若两者GCD=1,则必有除数和余数GCD=1.于是,求出除数剩余系,再在原位置加上被除数的倍数得到第k个数.
#include <iostream>#include <cstdio>#include <algorithm>#define N 1000005using namespace std;const int Np=1005;bool iscoprime[N],isprime[Np];int coprime[N],cp,prime[Np],np,fac[100],fp;void initial(){ memset(isprime,true,sizeof(isprime)); np=0; for(int i=2;i<Np;i++){ if(isprime[i]){ prime[np++]=i; for(int j=i*i;j<Np;j+=i) isprime[j]=false; } }}void Fcoprime(int m){ int p=m; fp=0; for(int i=0;i<np&&prime[i]*prime[i]<=p;i++){ if(p%prime[i]==0){ while(p%prime[i]==0) p/=prime[i]; fac[fp++]=prime[i]; } } if(p>1) fac[fp++]=p; memset(iscoprime,true,sizeof(bool)*(m+2)); cp=1; for(int i=0;i<fp;i++){ for(int k=1;k*fac[i]<m;k++) iscoprime[k*fac[i]]=false; } coprime[0]=0; for(int i=1;i<m;i++) if(iscoprime[i]){ coprime[cp++]=i; }}int main(){ initial(); int m,k; while(scanf("%d%d",&m,&k)!=EOF){ if(m==1){ printf("%d\n",k); continue; } Fcoprime(m); __int64 ans; int T=k/(cp-1); if(k%(cp-1)==0){ ans=(__int64)(T-1)*(__int64)m+(__int64)coprime[cp-1]; } else ans=(__int64)T*(__int64)m+(__int64)coprime[k%(cp-1)]; printf("%I64d\n",ans); } return 0;}
POJ 2773
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。