codeforces 995C

题意:从L到R 找有几个x,使x=a^p(a>0,p>1)

题解:

一开始把所有符合的次方都存到vector,然后MLE

可以看到1e6^3=1e18,所以可以将二次方单独来求,其他次方存到vector中二分写

注意点:

upper_bound()-lower_bound()

vec.erase(unique(vec.begin(), vec.end()), vec.end());

找二次方不用sqrt,精度不够,用二分来查找

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const int maxn=1005;
vector<ll> vec;
const ll inf=1e18;
ll L,R;
ll find(ll num){
    ll left=1;ll right=1000000000;
    while(left<=right){
        ll mid=(left+right)>>1;
        if(mid*mid>=num){
            right=mid-1;
        }else{
            left=mid+1;
        }
    }
    return right+1;
}
inline void init()
{
    for(ll i=2;i<=1000000;i++){
        ll x = floor(sqrt(i));
        if(x*x == i) continue;
        ll num=i*i*i;
        while(1){
            vec.push_back(num);
            if(num<=inf/(i*i)){
                num*=(i*i);
            }else{
                break;
            }
        }
    }
    sort(vec.begin(),vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
}
int main(){
    freopen("in.txt","r",stdin);
    int q;
    scanf("%d",&q);
    init(); 
    while(q--){
        scanf("%lld%lld",&L,&R);
        ll index1=upper_bound(vec.begin(),vec.end(),R)-vec.begin();
        ll index2=lower_bound(vec.begin(),vec.end(),L)-vec.begin();
        ll ans=index1-index2;
    //    cout<<ans<<"\n";
    //    cout<<find(R+1)<<" "<<find(L)<<"\n";
        ans+=find(R+1)-find(L);
        printf("%lld\n",ans);
    }
}

 

posted @ 2020-02-28 14:52  aaaaaaaaaaaaaa123  阅读(230)  评论(0)    收藏  举报