Codeforces Round #471 (Div. 2) C. Sad powers

C. Sad powers

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You're given Q queries of the form (L, R).

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 = ap.

Input

The first line contains the number of queries Q (1 ≤ Q ≤ 105).

The next Q lines contains two integers LR each (1 ≤ L ≤ R ≤ 1018).

Output

Output Q lines — the answers to the queries.

Example
input
Copy
6
1 4
9 9
5 7
12 29
137 591
1 1000000
output
2
1
0
3
17
1111
Note

In query one the suitable numbers are 1 and 4.

 

这个题目有些难度,主要是压缩时间,需要对数据进行一些处理和分类,首先1e18没有超long long ,先固定指数p,x^p <= 1e18 可以推导出 x <= 10^(18/p) 。若 p = 2, 则有 10^9 个的数字满足条件,若 p >= 3, 则最多有 10^6 的数字满足条件。所以先预处理,把所有不是完全平方数且满足 x^p<=1e18(p>=3) 的x都加入到vector, 排序去重,对于每次查询输出  sqrt(R) - sqrt(L-1) + upper_bound(R) - lower_bound(L)。对于查询x的平方根,用二分查找。

总的时间复杂度为 (1e6 + Qlog1e18)。

复制代码
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
vector<ll>g;

ll root(ll x)                   //二分查找平方根
{
    ll left = 0, right = 1e9;
    ll mid,ans;
    while (left<=right)
    {
        mid = (left+right)>>1;
        if (mid*mid<=x)
        {
            ans = mid;
            left = mid+1;
        }
        else right = mid-1;
    }
    return ans;
}

void init()                                  //预处理p>=3的数
{
    g.clear();
    for (ll i=2; i<=1e6; i++)
    {
        double t = 1.0*i*i*i;
        ll  s = i*i*i;
        while (t<2e18)
        {
            ll root_s = root(s);
            if (root_s*root_s<s)
            g.push_back(s);
            t *= i;
            s *= i;
        }
    }
    sort(g.begin(),g.end());
    int sz = unique(g.begin(),g.end())-g.begin();
}

int main()
{
    init();
    int q;
    scanf("%d",&q);
    ll l,r;
    while (q--)
    {
        scanf("%I64d %I64d",&l,&r);
        int ans1 = upper_bound(g.begin(),g.end(),r) - lower_bound(g.begin(),g.end(),l);
        int ans2 = root(r) - root(l-1);
        printf("%d\n",ans1+ans2);
    }
    return 0;
}
View Code
复制代码

 

posted @   yosoro  阅读(265)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示