Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 5258 | Accepted: 1576 |
Description
Input
Output
Sample Input
2006 1 2006 2 2006 3
Sample Output
1 3 5
Source
/* //这个题可以分段做,在到m之间与m互素的数有m的欧拉个, //(第一反应把以前用过的oula函数调了出来,)同样可推出m+1到2m之间, //n*m+1到(n+1)*m之间与m互素的个数也相同,,因为若k与m互素, //则k+n*m与m也互素,因为(n*m+K)%m=k%m;,,从而这题只要先求出-m之间与m 互素的数res[i]和总个数存入res[0], //若a[0]<k;,则为((k-1)/res[0])*m+res[k%res[o]],这里有一个小问题有注意是当res%res[0]==0时k=res[0]; //那么剩下的问题就是求1-m之间与m互素的数了,因为m<1000000如果暴力的话可能会超时,,, //求互素的问题这时就要想到伟大的欧拉大牛了,他证明了任何一个数可以分拆成N个素数的T[k]次方的积, //即n=p1^t1*…*pk^tk,,,从而再通过筛法筛掉m的素因子倍数的数,则剩下的就是和m互素的数了,存入数组res[]就OK了 //其实因为(n*m+K)%m=k%m,所以先求1-m内与m互质的数,然后这些数+(n*m),就是其他与m互质的数了,而那个n又可以根据 //(n*m+K)%m=k%m这条公式得到,首先是求出m的欧拉函数值phi[m],可知区间[1, m - 1]中有phi[m]个数与m互质。 //同样,在区间[n*m + 1, (n + 1) * m]中必然也有phi[m]个数与m互质,并且这phi[m]个数与[1 - m - 1]的phi[m]个数是"一一对应"的 //因此就可以先求1-m的互质数,然后再加上n*m就可以求第k个了这个时间很快47ms*/ #include<cstdio> #include<cstring> #include<cmath> const int N = 1000010; bool is_p[N];//判断素数 int prime[N];//存素数 int p[N]; int res[N]; int n,k; void getpri() { memset(is_p,true,sizeof(is_p)); int num=0; prime[++num]=2; for(int i=3;i*i<=N;i+=2) if(is_p[i]) { for(int j=i*i;j<N;j+=i) is_p[j]=false; } for(int i=3;i<N;i+=2) if(is_p[i]) prime[++num]=i; prime[0]=num; } void getp(int n)//求因子 { int num=0; for(int i=1;prime[i]*prime[i]<=n;i++) { if(n%prime[i]==0) { p[++num]=prime[i]; while(n%prime[i]==0) n=n/prime[i]; } } if(n>1) p[++num]=n; p[0]=num; } void eular()//晒互质数 { getp(n); memset(is_p,true,sizeof(is_p)); for(int i=1;i<=p[0];i++) { for(int j=p[i];j<=n;j+=p[i]) is_p[j]=false;//把m的因子和它的因子的倍数都晒去,剩下的就是互质的了 } int num=0; res[++num]=1; for(int i=2;i<=n;i++) if(is_p[i]) res[++num]=i; res[0]=num; } int main() { getpri(); __int64 ans; while(scanf("%d%d",&n,&k)!=EOF) { eular();//求出所有跟m互质的数 int x=k%res[0]; if(x==0) x=res[0]; __int64 y=(k-1)/res[0]; ans=y*n+res[x]; printf("%I64d/n",ans); } return 0; }