注:fjutoj基本每周都有一次周赛,欢迎大家都来参加!
网址:http://59.77.139.92/index.jsp
A题:来源 POJ 2773
题意:给两个数m和k,问第k 个和m 互素的数是多少(从1到无穷大)。
思路:
二分 + 容斥
先求出m 的素因子p[],数x 和m 互素就意味着x 不存在p 数组中的任意一个素因子,现在要 求n 下面不存在p[]素因子的数的数量可以转化为,n-存在p[]中任意一个素因子的数的个数(经典题型,用容斥可以求),现在二分(k,INF)可以求出答案。
1 #include<stdio.h> 2 #define N 1000010 3 #define LL long long 4 const LL INF = 0x7fffffffffffffff; 5 bool pri[N]; 6 int prim[N], po=0; 7 void Init() 8 { 9 for(int i=2;i<N;i++) 10 { 11 if(!pri[i]) prim[po++]=i; 12 for(int j=0;j<po&&(LL)i*prim[j]<N;j++) 13 { 14 pri[i*prim[j]]=1; 15 if(i%prim[j]==0) break; 16 } 17 } 18 } 19 20 int data[30], co; 21 22 void fun(int x) 23 { 24 int i=0; 25 co=0; 26 while(i<po && (LL)prim[i]*prim[i]<=x) 27 { 28 bool c=0; 29 while(x%prim[i]==0) 30 { 31 c=1; 32 x/=prim[i]; 33 } 34 if(c) data[co++]=prim[i]; 35 i++; 36 } 37 if(x!=1) data[co++]=x; 38 } 39 40 void dfs(int limit, int j, LL y, LL now, LL &all) 41 { 42 if(limit==0) 43 { 44 all += y/now; 45 return ; 46 } 47 for(int i=j; i<co; i++) 48 { 49 dfs(limit-1, i+1, y, now*data[i], all); 50 } 51 } 52 LL solve(LL x) 53 { 54 LL sum=x, flag=-1; 55 for(int i=1; i<=co; i++) 56 { 57 LL all=0; 58 dfs(i, 0, x, 1, all); 59 sum+=flag*all; 60 flag *= -1; 61 } 62 return sum; 63 } 64 65 LL er(LL l, LL r, LL x) 66 { 67 while(l<r) 68 { 69 LL mid = (l+r)/2; 70 if(solve(mid)>=x) r=mid; 71 else l=mid+1; 72 } 73 return l; 74 } 75 76 int main() 77 { 78 Init(); 79 int x,y; 80 while(~scanf("%d%d",&x, &y)) 81 { 82 fun(x); 83 printf("%lld\n", er(y, INF, y)); 84 } 85 return 0; 86 }