1. 程式人生 > >codeforces 955C - Sad powers

codeforces 955C - Sad powers

init tar turn -- sqrt upper 一個 push codeforce

傳送門

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\n", ans); 51 } 52 53 return 0; 54 }

codeforces 955C - Sad powers