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=2,也可以使用二分查找来得到x的个数。
这两种情况会有重复的x,所以要在预处理的时候把所有的平方数去掉。

代码:

 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5
 6 typedef long long int LLI;
 7 const LLI UP = 1e18;
 8 vector<LLI> V;
 9
10 LLI root(LLI n) { // 二分查找n的平方根r(n <= r*r)
11     LLI L = 1, R = 1e9 + 1;
12     while(L < R) {
13         LLI M = L + (R - L) / 2;
14         if(M * M >= n) R = M;
15         else L = M + 1;
16     }
17     return L;
18 }
19
20 void constant() {
21     vector<LLI> V2 = {1};
22     int u = 1e6;
23     for(int n = 2; n <= u; n++) {
24         for(LLI i = 1LL * n * n * n; ; i *= n) {
25             V2.push_back(i);
26             if(i > UP / n) break; // 防止 long long 溢出
27         }
28     }
29     sort(V2.begin(), V2.end());
30     V2.erase(unique(V2.begin(), V2.end()), V2.end());
31     for(int i = 0; i < V2.size(); i++) {
32         LLI r = root(V2[i]);
33         if(r * r != V2[i]) V.push_back(V2[i]);
34     }
35 }
36
37 int main() {
38     constant(); // 预处理
39     int q;
40     LLI L, R;
41     scanf("%d", &q);
42     while(q--) {
43         scanf("%I64d%I64d", &L, &R);
44         LLI ans = upper_bound(V.begin(), V.end(), R)
45                 - lower_bound(V.begin(), V.end(), L);
46         ans += root(R+1) - root(L);
47         printf("%I64d\n", ans);
48     }
49     return 0;
50 }

原文地址:https://www.cnblogs.com/hkxy125/p/8796625.html

时间: 2024-07-31 23:43:56

Codeforces 955C - Sad powers(数论 + 二分)的相关文章

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的情况,对上界

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

hdu 3641 数论 二分求符合条件的最小值数学杂题

http://acm.hdu.edu.cn/showproblem.php?pid=3641 学到: 1.二分求符合条件的最小值 /*==================================================== 二分查找符合条件的最小值 ======================================================*/ ll solve() { __int64 low = 0, high = INF, mid ; while(low <=

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 374D Inna and Sequence 二分+树状数组

题目链接:点击打开链接 给定n个操作,m长的序列a 下面n个数 if(co>=0)则向字符串添加一个co (开始是空字符串) else 删除字符串中有a的下标的字符 直接在序列上搞,简单模拟 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h&

POJ1845 数论 二分快速取余

大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题思路: 应用定理主要有三个: (1)   整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数 (2)   约数和公式: 对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 有A的所有因子之和为 S = (1+p1+p1^2+p1^3+...p1^k1

Codeforces 8D Two Friends 三分+二分+计算几何

题目链接:点击打开链接 题意:点击打开链接 三分house到shop的距离,二分这条斜边到cinema的距离 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<set> #include<queue> #include<vector> #include<

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