首页 > 代码库 > 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