Codeforces 955C Sad powers(数论)

Codeforces 955C Sad powers

题意

q组询问,每次询问给定L,R,求[L,R]区间内有多少个数可以写成ap的形式,其中a>0,p>1,1 ≤ L ≤ R ≤ 1e18。

思路

  • 对于p>2的情况,由于随着指数p的增大,小于1e18的p次幂的数量会急剧减小,总数量的级别在1e6多左右,因此可预处理。L,R不超过1e18,可以直接枚举数字1-1e6,将每个数字不超过1e18的且不是平方数的p次幂推入数组中,排序去重。以便回答询问时可二分求数量。
  • 对于p=2的情况,对上界直接开方,即可知道有多少个平方数。

做法不难,但容易看不清复杂度,以至于想不到做法。建议手写开方,否则误差较大。

代码

#include<bits/stdc++.h>
#define dd(x) cout<<#x<<" = "<<x<<" "
#define de(x) cout<<#x<<" = "<<x<<"\n"
#define sz(x) int(x.size())
#define All(x) x.begin(),x.end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef priority_queue<int> BQ;
typedef priority_queue<int,vector<int>,greater<int> > SQ;
const int maxn=1e5+10,mod=1e9+7,INF=0x3f3f3f3f;
ll Sqrt(ll x)
{
    ll l=1,r=x,ans=0;
    while (l<=r)
    {
        ll mid=(l+r)>>1;
        ld mul=ld(mid)*mid;
        if (mul<x)
            l=mid+1,ans=mid;
        else if (mul>x)
            r=mid-1;
        else
            return mid;
    }
    return ans;
}
vector<ll> v;
vector<ll>:: iterator End;
void init()
{
    for (ll i=2;i<=1e6;++i)
    {
        ll a=i*i*i;
        ld _a=a;
        while (_a<=1e18)
        {
            ll t=Sqrt(a);
            if (t*t!=a)
                v.pb(a);
            a*=i;
            _a*=i;
        }
    }
    sort(All(v));
    End=unique(All(v));
}
ll count(ll n)
{
    ll p=upper_bound(v.begin(),End,n)-v.begin();
    return Sqrt(n)+p;
}
int main()
{
    init();
    int n;
    cin>>n;
    while (n--)
    {
        ll l,r;
        scanf("%lld%lld",&l,&r);
        printf("%lld\n",count(r)-count(l-1));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/orangee/p/9975085.html

时间: 2024-10-17 17:52:43

Codeforces 955C Sad powers(数论)的相关文章

Codeforces 955C - Sad powers(数论 + 二分)

链接: http://codeforces.com/problemset/problem/955/C 题意: Q次询问(1≤Q≤1e5),每次询问给出两个整数L, R(1≤L≤R≤1e18),求所有符合条件的整数x的个数.条件为:L≤x≤R,x = a的p次方(a, p为整数且a>0, p>1). 分析: 一.当指数p=3时,底数a最多有1e6个,由于指数增加时底数收敛得很快,所以我们可以将p>=3时的所有x放进vector里排序去重(预处理),求x的个数的时候二分查找即可.二.对于p=

codeforces 955C - Sad powers

传送门 Q(1?≤?Q?≤?105)组询问,给定L.R (1?≤?L?≤?R?≤?1018).,求闭区间内有多少个数能表示为一个数的k次幂(k > 1) 对于k=2的情况可以直接求根做差,对于k>3的情况,由于所有的数数目很少,我们可以直接枚举出来.过程中注意判重和平方数(否则与情况1重复计算) 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vec

UVA 10622 - Perfect P-th Powers(数论)

UVA 10622 - Perfect P-th Powers 题目链接 题意:求n转化为b^p最大的p值 思路:对n分解质因子,然后取所有质因子个数的gcd就是答案,但是这题有个坑啊,就是输入的可以是负数,负数的情况比较特殊,p只能为奇数,这时候是要把答案不断除2除到为奇数即可. 代码: #include <stdio.h> #include <string.h> #include <math.h> long long n; int prime[333333], vi

Codeforces 413B Spyke Chatting(数论简单)

题目链接:Codeforces 413B Spyke Chatting 题目大意:n个人,m种聊天器,k次发送消息,然后给出n*m的矩阵,如果g[i][j]为1,则表示i号人会使用j号聊天器,接着给出k次消息发送者和聊天器,如果i在j种聊天器上发送了一条消息,那么所有使用j种聊天器的人都会接受到消息.现在要求每个人会接受到几条消息,自己发送的不算. 解题思路:分别记录每个聊天器上有多少个消息,以及每个人发送了多少条消息,然后计算每个人接受到多少条消息的时候只要将这个人所使用的各个聊天器消息数取和

[CodeForces - 1225C]p-binary 【数论】【二进制】

[CodeForces - 1225C]p-binary [数论][二进制] 题目描述 Time limit 2000 ms Memory limit 524288 kB Source Technocup 2020 - Elimination Round 2 Tags bitmasks brute force math *1600 Site https://codeforces.com/problemset/problem/1225/c 题面 Example Input1 24 0 Output

Codeforces 1034C Region Separation - 数论 - 动态规划

题目传送门 传送站I 传送站II 传送站III 题目大意 给定一个$n$个点的树$T = (G, V)$,每个点有一个正整数点权$a_{i}$.整棵树是第1级划分.定义第$i$级划分是将第$i - 1$级划分中的每个区域划分成至少两个新的区域,并且所有区域都是一个连通块,每个点在每一级中只属于一个区域,在同一级划分内每个区域内的点的点权和相等.一种划分方案包含它划分的每一级.两种划分方案不同当且仅当它们划分的级数不同,或者存在一个点在某一级中它们在两种划分方案中属于不同区域. 之前好像某次noi

codeforces #271E Three Horses 数论

题目大意:有一种卡片,正面和背面各写着一个整数,可以用一个有序数对(x,y)表示 有三种操作: 1.出示一张卡片(x,y),获得一张卡片(x+1,y+1) 2.出示一张卡片(x,y)(x,y都是偶数),获得一张卡片(x2,y2) 3.出示两张卡片(x,y)和(y,z),获得一张卡片(x,z) 一个人想要卡片(1,a1),(1,a2),(1,a3),...,(1,an),他可以携带一张初始卡片(x,y)(1≤x<y≤m),求有多少种方案 首先我们发现: 第一个操作不改变y?x的值 第二个操作可以使

Codeforces 762A k-th divisor(数论)

题目链接:k-th divisor 直接暴力-- 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i,a,b) for(int i(a); i <= (b); ++i) 6 #define LL long long 7 8 LL n, k, h, ans; 9 int num; 10 11 int main(){ 12 13 scanf("%lld%lld", &n, &a

Codeforces 622F 「数学数论」「数学规律」

题意: 给定n和k,求 1 ≤ n ≤ 109, 0 ≤ k ≤ 106 思路: 题目中给的提示是对于给定的k我们可以求出一个最高次为k+1的关于n的通项公式. 根据拉格郎日插值法,我们可以通过k+2个离散的点来确定这个通项.所以求出前k+2项,然后就可以确定公式. 拉格郎日差值法传送门:http://www.guokr.com/post/456777/ 最后得出的公式是酱紫的:(公式来自卿学姐博客) 然后问题来了,有除法如何搞定模运算...这个就用到逆元的运算了,逆元的定义就是大家都学过的离散