其他分享
首页 > 其他分享> > Codefoces 955C 题解

Codefoces 955C 题解

作者:互联网

题意简述

多组数据。每次给定lll,rrr(l,rl,rl,r都&lt;=1e18&lt;=1e18<=1e18),求lll~rrr中有多少xxx满足x=apx=a^px=ap,其中aaa和ppp是两个整数满足a&gt;0,p&gt;1a&gt;0,p&gt;1a>0,p>1。

数据

输入:
6
1 4
9 9
5 7
12 29
137 591
1 1000000

输出:
2
1
0
3
17
1111

思路

会发现,当p&gt;=3p&gt;=3p>=3时,使得0&lt;=ap&lt;=1e180&lt;=a^p&lt;=1e180<=ap<=1e18的aaa并不多,p=3p=3p=3大概有1e61e61e6,然后后面更少。经计算,总共的个数(去重后)是100333210033321003332,就比1e61e61e6多一点。考虑暴力存下,排序去重后存着。p&gt;=3p&gt;=3p>=3的情况只要upperboundlowerboundupperbound-lowerboundupperbound−lowerbound即可。记为a1a_1a1​。

那如何处理p=2p=2p=2的情况?

相当于求有多少aaa满足l&lt;=a2&lt;=rl&lt;=a^2&lt;=rl<=a2<=r。

我们会发现,如果设S(n)S(n)S(n)为满足1&lt;=a2&lt;=n1&lt;=a^2&lt;=n1<=a2<=n的aaa个数,则我们要求的就是S(r)S(l1)S(r)-S(l-1)S(r)−S(l−1)。

由数学常识得,S(n)=nS(n)=\sqrt{n}S(n)=n​。

故我们要求的就是rl1\sqrt{r}-\sqrt{l-1}r​−l−1​。记为a2a_2a2​

然后只要把a1a_1a1​和a2a_2a2​加一起即可。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Max=1000000ll*1000000ll*1000000ll;//1e18

int Root(int x)
{
    return (int)sqrt(x*1.0+0.5);
}
vector<int>tmp;
void Build()
{
    for(int i=2;i<=1000000;i++)//枚举底数
    {
        int s=i*i*i;//至少三次方
        while(s<=Max)
        {
            int rs=Root(s);
            if (rs*rs<s) tmp.push_back(s);
            //这个就是判s是否是平方数,为了避免和后面考虑p=2的情况重合

            if (s>Max/i) break;//如果爆了赶快退出
            else s*=i;//没爆继续乘
        }
    }
    sort(tmp.begin(),tmp.end());
    tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end());//排序去重,方便lower_bound和upper_bound
    //printf("%d\n",tmp.size());
    //=1003332,如果要自己写(即不完全Copy我的),珂以先对一下这个答案
}

int l,r;
void Solve()
{
    int a1=upper_bound(tmp.begin(),tmp.end(),r)-lower_bound(tmp.begin(),tmp.end(),l);
    int a2=Root(r)-Root(l-1);
    printf("%I64d\n",a1+a2);//上面说的a1和a2
}

main()
{
    Build();
    int T;scanf("%I64d",&T);
    while(T--)
    {
        scanf("%I64d%I64d",&l,&r);
        Solve();
    }
    return 0;
}

标签:tmp,gt,end,Codefoces,题解,955C,3p,int,lt
来源: https://blog.csdn.net/LightningUZ/article/details/89040080