Codeforces 955C 数学
C. Sad powers
题意:
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 = a^p.
q个询问,每次求在区间 [L,R] 内有多少个幂。 q<=1e5, 1<=L<=R<=1e18。
tags:
数学题
首先肯定会想到预处理出 [1,1e18] 内所有的幂,但是指数为 2 的幂会有 1e9 个,所以我们先预处理出所有指数 >2 的幂,只有 1e6 级别。
然后对每个询问,指数为 2 的个数就直接开根号,指数 >2 的在预处理的数里面二分就好了。
// 955C
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = 5000005;
ll num[N]; int cnt;
void Init()
{
cnt = 0;
for(ll i=2; i<=1e6; ++i)
{
ll sum = i;
do {
sum *= i;
ll tmp=(ll)sqrt(sum);
if(tmp*tmp!=sum) num[++cnt]=sum;
}while(sum<=1e18/i);
}
sort(num+1, num+1+cnt);
cnt = unique(num+1, num+1+cnt) - (num+1);
}
ll query(ll x) {
int pos = upper_bound(num+1, num+1+cnt, x) - num;
return pos-1;
}
ll solve(ll L, ll R)
{
ll ret = ((ll)sqrt(R)) - ((ll)sqrt(L-1));
return ret + query(R) - query(L-1);
}
int main()
{
Init();
int q; ll L, R;
scanf("%d", &q);
while(q--)
{
scanf("%lld%lld", &L, &R);
printf("%lld\n", solve(L, R));
}
return 0;
}