cf955 C. Sad powers(数学,打表)
题意:
每次询问 L,R ,输出 L 与 R 之间形如 \(a^p,a\ge 1,p\ge 2\) 的数
L,R <= 1e18
思路:
1~n中的平方数恰有 \(ceil(\sqrt n)\) 个,立方数不超过 1e6 个,更高次方的数更少。
对 \(p=2\) ,答案是 \(sqrt(R)-sqrt(L-1)\);
对 \(p\ge 3\),打表。然后二分数数。
要自己写 sqrt(),要不然会有精度问题。。。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e18;
ll sqrt(ll x)
{
ll l = 0, r = 1e9 + 1;
while (l < r - 1)
{
ll m = (l + r) / 2;
if (m * m > x) r = m;
else l = m;
}
return l;
}
vector<ll> mi;
void init() //打表
{
for(ll i = 2; i <= 1e6; i++)
{
for(ll j = i*i*i; j <= N; j *= i)
{
ll t = sqrt(j); //别加进平方数
if(t * t != j) mi.push_back(j);
if(j > N/i) break; //小心越界
}
}
sort(mi.begin(), mi.end()); //去重
mi.erase(unique(mi.begin(), mi.end()), mi.end());
}
signed main()
{
init();
int T; cin >> T; while(T--)
{
ll l, r; scanf("%lld%lld", &l, &r);
printf("%lld\n", (ll)sqrt(r) - (ll)sqrt(l-1)
+ (ll)(upper_bound(mi.begin(),mi.end(),r) - lower_bound(mi.begin(),mi.end(),l))
);
}
return 0;
}

浙公网安备 33010602011771号