codeforces 955C - Sad powers

传送门

 

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 }

 

posted @ 2018-05-09 19:25  xFANx  阅读(168)  评论(0编辑  收藏  举报