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;
}

posted @ 2021-12-26 23:05  Bellala  阅读(159)  评论(0)    收藏  举报