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 > 0p > 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
Copy
2
1
0
3
17
1111
Note

In query one the suitable numbers are 1 and 4.


题意:问[L,R]的区间内有多少个数是幂p次(>=2)得来的数

思路:

1.暴力,处理出所有1,1e18内所有的幂次数,用upper_bound处理出落在区间[L,R]内的幂次数个数.

2.突然发现暴力不行,怎么整? 发现对于p=2的情况可以单独求解(根号有坑点啊),数量级到了1e9 . 而p>=3的数量级<=1e6 . 

#include<bits/stdc++.h>
#define PI acos(-1.0)
using namespace std;
typedef long long ll;

const int N=1e5+50;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;

vector <ll> vec;
map <ll,int> mp;

bool square(ll x){
    ll t=sqrt(x);
    if(t*t==x || (t+1)*(t+1)==x || (t-1)*(t-1)==x)  return true;
    return false;
}

void prepare(){
    vec.push_back(1);
    for(ll i=2;i<=1e6;++i){
        for(ll t=i*i*i;t<=1e18;t*=i){
            if(!mp[t] && !square(t)) mp[t]=1,vec.push_back(t); ///去重,去平方数
            if(1ll*1e18/i<t)    break;
        }
    }
    sort(vec.begin(),vec.end());
}

ll f(ll x){
    ll l=1,r=1e9;
    ll ans=0;
    while(l<=r){
        ll mid=(l+r)/2;
        if(mid*mid<=x)  ans=mid,l=mid+1;
        else     r=mid-1;
    }
//    cout <<"~~"<<ans<<endl;
    return ans;
}

int main(void){
    prepare(); /// del 1e6 p>=3    cout <<"BUG"<<endl,
    ll q,l,r;
    cin >>q;
    while(q--){
        scanf("%I64d%I64d",&l,&r);
        ll ans=0;
        ans+= f(r)-f(l-1);//用二分求根号 || 判断是否平方数也可以
//        cout <<"ans="<<ans<<endl;
        ans+=upper_bound(vec.begin(),vec.end(),r)-upper_bound(vec.begin(),vec.end(),l-1);
        if(l==1)    ans--;
        printf("%I64d\n",ans);
    }

    return 0;
}
/**************

**************/