CodeForce-955C

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 L, R 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.

题目大意:

找到L—R之间的所有可以由x的p次幂所表示的数

思路:

虽然暴力是个好东西,但wa题也是很容易。

最初的想法是:遍历每个数字的每次幂,但很明显是行不通的。有趣的是,走不通的路,也还要试一下看看能过几个样例。然后wa在了第三个样例上。。。有兴趣可以看一眼真·暴力代码。如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int vis[100000000];
 4
 5 typedef long long ll;
 6
 7 ll push_pow(ll a,ll b)
 8 {
 9     ll ans=1;ll base=a;
10     while(b)
11     {
12         if(b%2) ans*=base;
13         base*=base;
14         b/=2;
15     }
16     return ans;
17 }
18
19 ll slove(ll l,ll r)
20 {
21     memset(vis,0,sizeof(vis));
22     int flag=1;ll ans1=0,ans2=0;
23     for(int i=2;flag;i++)
24     {
25         for(int j=2;;j++)
26         {
27             if(l>=push_pow(i,j)&&!vis[push_pow(i,j)])
28             {
29                 ans1++;
30             }
31             if(r>=push_pow(i,j)&&!vis[push_pow(i,j)])
32             {
33                 vis[push_pow(i,j)]=1;ans2++;
34             }
35             else if(j==2&&!vis[push_pow(i,j)])
36             {
37                 flag=0;
38                 break;
39             }
40             else break;
41         }
42     }
43     return ans2-ans1;
44 }
45
46 int main()
47 {
48     ll T,l,r;
49     scanf("%lld",&T);
50     for(int o=1;o<=T;o++)
51     {
52         scanf("%lld%lld",&l,&r);
53         if(l==1) printf("%lld\n",1+slove(l-1,r));
54         else printf("%lld\n",slove(l-1,r));
55     }
56     return 0;
57 }

真·暴力

暴力不是ac的秘诀,那么这道题该怎么解决呢?在思考无果的情况下,百度。。。

事实它告诉我,这题不是我原先可以解决的。于是乎,涨知识了。

言归正传,我们可以把问题分割,分成两部分,一部分是二次方,一部分是p次方(p>2)。

二次方不必说,二分查找很容易解决问题。

主要是p次方,当p=3时,1e18开三次根号1e6,复杂度在可接受范围内。

而当p>3时,由于幂函数的增幅极大,所以到大于1e18花费的时间是很少的,以最多次幂的2举例,1e18没有爆longlong,那么次数少于64,很明显,花费也是可以接受的。

AC代码如下:

 1 #include<stdio.h>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 typedef long long ll;
 7 vector<ll>q;
 8
 9 int root(ll x)      //找根
10 {
11     ll left=0;ll right=1e9;   //left必须从0开始,因为调用函数时会有x==0的情况
12     ll mid,ans;
13     while(left<=right)
14     {
15         mid=(left+right)>>1;
16         if(mid*mid<=x)
17         {
18             ans=mid;
19             left=mid+1;
20         }
21         else
22         {
23             right=mid-1;
24         }
25     }
26     return ans;
27 }
28
29 void init()   //p>2时,可以由x的p次方表示的数
30 {
31     q.clear();
32     for(ll i=2;i<=1e6;i++)
33     {
34         double t=1.0*i*i*i;
35         ll s=i*i*i;
36         while(t<2e18)
37         {
38             ll root_s=root(s);
39             if(root_s*root_s<s)
40             q.push_back(s);
41             t*=i;s*=i;
42         }
43     }
44     sort(q.begin(),q.end());    //下面会解释
45     unique(q.begin(),q.end());
46 }
47
48 int main()
49 {
50     init();
51     ll T;
52     ll l,r;
53     scanf("%lld",&T);
54     for(int i=1;i<=T;i++)
55     {
56         scanf("%lld%lld",&l,&r);
57         ll ans1=upper_bound(q.begin(),q.end(),r)-lower_bound(q.begin(),q.end(),l);//下面会解释
58         ll ans2=root(r)-root(l-1);
59         printf("%lld\n",ans1+ans2);
60     }
61     return 0;
62 }

unique()函数 

sort(q.begin(),q.end());
unique(q.begin(),q.end());   

独一无二的,该函数的作用是把相邻的两个相同的数字中消去一个,让我想起了天梯赛的1-8(AI牛批!

相邻的两个相同的数字,那么sort()函数的作用就体现在为unique()函数服务上了。

upper_bound()与lower_bound()函数

ll ans1=upper_bound(q.begin(),q.end(),r)-lower_bound(q.begin(),q.end(),l);

upper_bound()作用是返回[l,r)中第一个大于某个数字的元素,lower_bound()的作用是返回[l,r)中第一个大于某个数字的元素。

原文地址:https://www.cnblogs.com/noback-go/p/10659327.html

时间: 2024-10-03 15:59:15

CodeForce-955C的相关文章

CodeForce 448C 木片填涂问题

题目大意:有多片木片需要填涂,可以每次横着涂一行,也可以一次涂一列,当然你涂一行时遇到中间长度不够高的木片,填涂到此中断 这题目运用dfs能更容易的解出,虽然还是十分不容易理解 1 #include <iostream> 2 3 using namespace std; 4 5 #define N 5010 6 int a[N],n; 7 8 int Min(int c,int d) 9 { 10 return c<d?c:d; 11 } 12 int dfs(int c,int d,i

Codeforce 水题报告(2)

又水了一发Codeforce ,这次继续发发题解顺便给自己PKUSC攒攒人品吧 CodeForces 438C:The Child and Polygon: 描述:给出一个多边形,求三角剖分的方案数(n<=200). 首先很明显可能是区间dp,我们可以记f[i][j]为从i到j的这个多边形的三角剖分数,那么f[i][j]=f[i][k]*f[j][k]*(i,j,k是否为1个合格的三角形) CodeForces 438D:The Child and Sequence 描述:给一个序列,要求支持区

codeforce 285 div2 D 题解

codeforce 285 div2 D 题解 说明 这道题目是看了思路分析才知道的,关键问题在于数据量过大,需要快速检索的同时不能辅助空间过大. 因此利用了下面3种方法结合解决该问题 康拓展开与逆康拓展开 树状数组 二分查找 代码 /** * @brief Codeforces Round #285 (Div. 2) d * @file d.cpp * @author mianma * @created 2015/01/27 18:18 * @edited 2015/01/29 22:45 *

codeforce Pashmak and Buses(dfs枚举)

1 /* 2 题意:n个同学,k个车, 取旅游d天! 3 要求所有的学生没有两个或者两个以上的在同一辆车上共同带d天! 输出可行的方案! 4 5 对于d行n列的矩阵,第i行第j列表示的是第i天第j个同学所在的车号! 6 也就是保证所有行不全相同,即每一列都是不相同的! 7 如果每一列都不相同就是表示第j个同学(第j列)在这d天中不会和其他同学(列)在这d天中 都在同一辆车中! 8 9 思路:对于每一列我们枚举d天该学生所在的车号!它的下一列只保证有一个元素和它不同就行了!依次下去! 10 11

codeforce 605BE. Freelancer&#39;s Dreams

题意:给你n个工程,做了每个工程相应增长x经验和y钱.问你最少需要多少天到达制定目标.时间可以是浮点数. 思路:杜教思路,用对偶原理很简易.个人建议还是标准解题法,凸包+线性组合. 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include&

Codeforce 214 Div 2 B.Hometask

题目描述: Description Furik loves math lessons very much, so he doesn't attend them, unlike Rubik. But now Furik wants to get a good mark for math. For that Ms. Ivanova, his math teacher, gave him a new task. Furik solved the task immediately. Can you? Y

Codeforce 22B Bargaining Table

B. Bargaining Table Bob wants to put a new bargaining table in his office. To do so he measured the office room thoroughly and drew its plan: Bob's office room is a rectangular room n?×?m meters. Each square meter of the room is either occupied by so

Codeforce 9C - Hexadecimal&#39;s Numbers

One beautiful July morning a terrible thing happened in Mainframe: a mean virus Megabyte somehow got access to the memory of his not less mean sister Hexadecimal. He loaded there a huge amount of n different natural numbers from 1 to n to obtain tota

codeforce 128C Games with Rectangle 排列组合

Games with Rectangle Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Description In this task Anna and Maria play the following game. Initially they have a checkered piece of paper with a painted n?×?m rect

codeforce 泛做

1A - Theatre Square 题意:有一个规模为n*m的剧院,用a*a的地板来铺满,问需要多少块木板. 思路:水题. 1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<cstdio> 7 #include<vector> 8 #define