Codeforces Round #471 (Div. 2) C. Sad powers

C. Sad powers

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You're given Q queries of the form (L, R).

For each query you have to find the number of such x that L ≤ x ≤ R and there exist integer numbers a > 0, p > 1 such that x = ap.

Input

The first line contains the number of queries Q (1 ≤ Q ≤ 105).

The next Q lines contains two integers LR each (1 ≤ L ≤ R ≤ 1018).

Output

Output Q lines — the answers to the queries.

Example
input
Copy
6
1 4
9 9
5 7
12 29
137 591
1 1000000
output
2
1
0
3
17
1111
Note

In query one the suitable numbers are 1 and 4.

这个题目有些难度,主要是压缩时间,需要对数据进行一些处理和分类,首先1e18没有超long long ,先固定指数p,x^p <= 1e18 可以推导出 x <= 10^(18/p) 。若 p = 2, 则有 10^9 个的数字满足条件,若 p >= 3, 则最多有 10^6 的数字满足条件。所以先预处理,把所有不是完全平方数且满足 x^p<=1e18(p>=3) 的x都加入到vector, 排序去重,对于每次查询输出  sqrt(R) - sqrt(L-1) + upper_bound(R) - lower_bound(L)。对于查询x的平方根,用二分查找。

总的时间复杂度为 (1e6 + Qlog1e18)。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
vector<ll>g;

ll root(ll x)                   //二分查找平方根
{
    ll left = 0, right = 1e9;
    ll mid,ans;
    while (left<=right)
    {
        mid = (left+right)>>1;
        if (mid*mid<=x)
        {
            ans = mid;
            left = mid+1;
        }
        else right = mid-1;
    }
    return ans;
}

void init()                                  //预处理p>=3的数
{
    g.clear();
    for (ll i=2; i<=1e6; i++)
    {
        double t = 1.0*i*i*i;
        ll  s = i*i*i;
        while (t<2e18)
        {
            ll root_s = root(s);
            if (root_s*root_s<s)
            g.push_back(s);
            t *= i;
            s *= i;
        }
    }
    sort(g.begin(),g.end());
    int sz = unique(g.begin(),g.end())-g.begin();
}

int main()
{
    init();
    int q;
    scanf("%d",&q);
    ll l,r;
    while (q--)
    {
        scanf("%I64d %I64d",&l,&r);
        int ans1 = upper_bound(g.begin(),g.end(),r) - lower_bound(g.begin(),g.end(),l);
        int ans2 = root(r) - root(l-1);
        printf("%d
",ans1+ans2);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/youchandaisuki/p/8727575.html