POJ2773 二分+容斥原理 xingxing在努力
这一个题就是求解第k个和n互质的数, 像这种求解第k个数的一般都可以用二分解决, 前提是可以求得一个区间内满足条件的数的个数, 对于这一道题假设我们知道1-n的区间中和n互质的个数, 那么我们就可以通过二分快速的定位这个数。。利用容斥原理求出1-n中不与n互质的数的个数, 用n减去这个数就是要求得数。。代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <iostream> using namespace std; typedef long long LL; int m, k; int factor[50], cnt; void getfactor(int n) { cnt = 0; int m = sqrt(n+0.5); for(int i=2; i<=m; i++) if(n%i == 0) { factor[cnt++] = i; while(n%i==0) n/=i; } if(n > 1) factor[cnt++] = n; //不要忘记呀,贡献了几发wa } LL getnum(LL n) //获取1-n中和m互质的数的个数 { if(m == 1) return n; if(n == 1) return 1; LL res = n; for(int i=1; i<(1<<cnt); i++) { LL temp = i, a=0, b=1; for(int j=0; j<cnt; j++) { if((temp&1) == 1) { b *= factor[j]; a++; } temp >>= 1; } if((a&1)==1) res -= n/b; else res += n/b; } return res; } int main() { while(scanf("%d%d", &m, &k) == 2) { getfactor(m); LL low=1, high = (1LL<<62); LL ans; while(low <= high) { LL mid = (low+high)/2; LL num = getnum(mid); if(num > k) high = mid - 1; else if(num < k) low = mid + 1; else { ans = mid; high = mid - 1; } } cout<<ans<<endl; } return 0; }

浙公网安备 33010602011771号