很容易想到我们需要这样一个函数f(n)表示的是1~n的数字中在y sequence中的个数,于是可以想到用容斥来做,先假设答案是n然后计算n中y sequence的个数,然后n加上不够的,继续判断,一直迭代求出答案。
小技巧:预处理的时候素数设为负数方便判断容斥的时候是应该加还是减。
1 #include <iostream> 2 #include <cstring> 3 #include <vector> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 8 typedef long long ll; 9 int p[] = {-2,-3,-5,-7,-11,-13,-17,-19,-23,-29,-31,-37,-41,-43,-47,-53,-59,-61,-67}; 10 vector<int> v; 11 12 void init( int r ) 13 { 14 v.clear(); 15 for ( int i = 0; -p[i] <= r; i++ ) 16 { 17 int bound = v.size(); 18 for ( int j = 0; j < bound; j++ ) 19 { 20 if ( abs( v[j] * p[i] ) <= 63 ) 21 { 22 v.push_back( v[j] * p[i] ); 23 } 24 } 25 v.push_back(p[i]); 26 } 27 } 28 29 ll cal( ll n ) 30 { 31 ll res = 0; 32 for ( int i = 0; i < v.size(); i++ ) 33 { 34 ll tmp = pow( n + 0.5, 1.0 / abs(v[i]) ) - 1; 35 if ( v[i] < 0 ) res += tmp; 36 else res -= tmp; 37 } 38 return n - res - 1; 39 } 40 41 int main () 42 { 43 int t; 44 scanf("%d", &t); 45 while ( t-- ) 46 { 47 ll n, cp, tmp; 48 int r; 49 scanf("%I64d %d", &n, &r); 50 init(r); 51 cp = n, tmp = cal(cp); 52 while ( tmp < n ) 53 { 54 cp += n - tmp; 55 tmp = cal(cp); 56 } 57 printf("%I64d ", cp); 58 } 59 return 0; 60 }