题意:问[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; } /************** **************/