Q(1 ≤ Q ≤ 105)组询问,给定L、R (1 ≤ L ≤ R ≤ 1018).,求闭区间内有多少个数能表示为一个数的k次幂(k > 1)
对于k=2的情况可以直接求根做差,对于k>3的情况,由于所有的数数目很少,我们可以直接枚举出来。过程中注意判重和平方数(否则与情况1重复计算)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <cmath> 6 using namespace std; 7 8 typedef long long LL; 9 const LL up = 1e18; 10 11 int Q; 12 LL L, R; 13 14 vector<LL> vec; 15 16 void init() { 17 vector<LL> tmp; 18 tmp.push_back(1); 19 LL _up = 1e6; 20 for (LL i = 2; i < _up; i++) { 21 for (LL j = i * i * i; ; j *= i) { 22 tmp.push_back(j); 23 if (j > up / i) break; 24 } 25 } 26 sort(tmp.begin(), tmp.end()); 27 tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end()); 28 for (int i = 0; i < tmp.size(); i++) { 29 LL t = tmp[i]; 30 LL tt = sqrt(t); 31 if (tt * tt != t) vec.push_back(tmp[i]); 32 } 33 } 34 35 LL lower_root(LL A) { 36 LL t = sqrt(A); 37 if (t * t == A) t--; 38 return t; 39 } 40 41 42 int main() { 43 init(); 44 scanf("%d", &Q); 45 while (Q--) { 46 scanf("%lld%lld", &L, &R); 47 LL ans = upper_bound(vec.begin(), vec.end(), R) 48 - lower_bound(vec.begin(), vec.end(), L); 49 ans += lower_root(R + 1) - lower_root(L); 50 printf("%lld ", ans); 51 } 52 53 return 0; 54 }