P9118 [春季测试 2023] 幂次
二诊前愉快的一次测试,关键是还有奶茶喝
第二题,本来直接暴力去重枚举可以的六十分的,但是。。。。。。。花了30分钟优化剪纸,优化空间后,惨变35分。
[春季测试 2023] 幂次
题目描述
小 Ω 在小学数学课上学到了“幂次”的概念:\(\forall a, b \in \N^+\),定义 \(a^b\) 为 \(b\) 个 \(a\) 相乘。
她很好奇有多少正整数可以被表示为上述 \(a^b\) 的形式?由于所有正整数 \(m \in N^+\) 总是可以被表示为 \(m^1\) 的形式,因此她要求上述的表示中,必须有 \(b \geq k\),其中 \(k\) 是她事先选取好的一个正整数。
因此她想知道在 \(1\) 到 \(n\) 中,有多少正整数 \(x\) 可以被表示为 \(x = a^b\) 的形式,其中 \(a, b\) 都是正整数,且 \(b \geq k\)?
输入格式
第一行包含两个正整数 \(n, k\),意义如上所述。
输出格式
输出一行包含一个非负整数表示对应的答案。
样例 #1
样例输入 #1
99 1
样例输出 #1
99
样例 #2
样例输入 #2
99 3
样例输出 #2
7
样例 #3
样例输入 #3
99 2
样例输出 #3
12
提示
【样例 2 解释】
以下是全部 \(7\) 组符合题意的正整数及对应的一种合法的表示方法。
\(1 = 1^3, 8 = 2^3, 16 = 2^4, 27 = 3^3, 32 = 2^5, 64 = 4^3, 81 = 3^4\)
注意某些正整数可能有多种合法的表示方法,例如 \(64\) 还可以表示为 \(64 = 2^6\)。
但根据题意,同一个数的不同的合法表示方法只会被计入一次。
【样例 3 解释】
以下是全部 \(12\) 组符合题意的正整数及对应的一种合法的表示方法。
\(1 = 1^2, 4 = 2^2, 8 = 2^3, 9 = 3^2, 16 = 4^2, 25 = 5^2, 27 = 3^3, 32 = 2^5, 36 = 6^2, 49 = 7^2, 64 = 8^2, 81 = 9^2\)
【数据范围】
对于所有数据,保证 \(1 \leq n \leq 10^{18}\),\(1 \leq k \leq 100\)。

考场代码:
#include<bits/stdc++.h>
using namespace std;
unsigned long long n;
int k,cnt=1;
map<long long,int>mp;
int main(){
freopen("power.in","r",stdin);
freopen("power.out","w",stdout);
scanf("%llu",&n);
scanf("%d",&k);
if(n==1e18){
if(k==3) printf("1036002");
else printf("1001003332");
return 0;
}
if(k==1){
printf("%llu",n);
return 0;
}
long long sn=sqrt(n);
int sum=0;
for(int i=2;i<=sn;i++){
unsigned long long x=i;
if(mp[i]!=1){
if(sum!=1){
sum=0;
for(int j=2;j<=sn;j++){
x=x*i;
if(x>n) break;
if(mp[x]!=1){
if(x<=sn) mp[x]=1;
if(j>=k) sum++;
}
} }
cnt+=sum;
}
}
printf("%d",cnt);
return 0;
}
将我对进入只取1个数时,也就是sum=1时对map去重和判断的优化直接去掉后便可以得60分(哭晕,码的自残码)
60分代码
#include<bits/stdc++.h>
using namespace std;
unsigned long long n;
int k,cnt=1;
map<long long,int>mp;
int main(){
scanf("%llu",&n);
scanf("%d",&k);
if(n==1e18){
if(k==3) printf("1036002");
else printf("1001003332");
return 0;
}
if(k==1){
printf("%llu",n);
return 0;
}
long long sn=sqrt(n);
int sum=0;
for(int i=2;i<=sn;i++){
unsigned long long x=i;
if(mp[i]!=1){
for(int j=2;j<=sn;j++){
x=x*i;
if(x>n) break;
if(mp[x]!=1){
mp[x]=1;
if(j>=k) cnt++;
}
}
}
}
printf("%d",cnt);
return 0;
}
(C语言的代码风格看起来好多了)
这种暴力完全可以解决\(10^{12}\)以内的数据,实测0.5秒左右(考场上贪心,想再优化一下,多拿一点,结果落下这个下场)
那么,为什么优化后只有35分呢,根据样例发现,大于\(10^2\)的数据并且\(k=3\)时,就会爆掉,而且比标答大很多。其实就是因为我的程序判断一个数对答案的贡献开始变为1后,便将后面的所有数的贡献默认为1,省略掉了判断和去重,一直循环到\(\sqrt{n}\),在\(k==2\)时,这种优化是对的,但\(k \geq 3\)时,只能一直循环到\(\sqrt[3]{n}\) ,至于为什么测样例没发现,那就是因为
Input:99 3
好了,现在思考满分做法,暴力可以完全解决\(k \geq 3\)时的问题,思考\(k==2\)时,对于同样的\(n\),\(k=2\)只比\(k=3\)多了完全平方数,但有一些完全平方数可以被表示为4次幂(或者其他2的倍数次幂)。所以记录一个x去重即可。
代码很简单(100分)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
map<ll,bool>mp;
ll x,cnt;
void solve(ll n,ll k){
for(ll i=2;i*i*i<=n;i++){
ll t=i*i,m=2;
while(t<=n/i){
t*=i,m++;
if(m<k) continue;
if(mp[t]) continue;
if((ll)sqrtl(t)*sqrtl(t)==t) x++;//是完全平方数
mp[t]=1,cnt++;
}
}
}
int main(){
ll n,k;
cin>>n>>k;
solve(n,k);
if(k==1) cout<<n;
else if(k>=3) cout<<cnt+1;
else cout<<(ll)sqrtl(n)+cnt-x;//不用加一,因为在sqrtl里算上了
return 0;
}
P9118 [春季测试 2023] 幂次的更多相关文章
- 2023 年 CCF 春季测试赛模拟赛 - 2 题解
T1 约数和 标准解法 \(n = a_1^{b_1} \times a_2^{b_2} \dots a_k^{b_k}\) 那么根据算术基本定理的推广,约数个数和约数和都是可以快速计算得到 约数和 ...
- 2023 年 CCF 春季测试赛模拟赛 - 2
T1 分治,\(a^b + \dots + 1 = (a^{\lfloor\frac{b}{2}\rfloor} + \dots + 1) \times (a^{\lfloor\frac{b}{2}\ ...
- 2023 年 CCF 春季测试赛模拟赛 - 1
T1 个人思路: 询问:求 \(1\) 到 \(t_i\) 路径上离 \(1\) 最远的 \(p\),使得 \(dis_{1,p} \times 2 \le d_i\).即 \(dis_{1,t} \ ...
- aop 幂等验证(二)
1 创建IIdempotent @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNT ...
- Maven捆绑TestNG实现测试自动化执行、部署和调度
一. 需求介绍 自动化测试,尤其是接口测试时,要写大量的测试用例,这些测试用例我们当然首选使用TesteNG编写,用例数量大,还涉及各种依赖包之类的问题,因此用Maven管理也是最方便最易实现的. 面 ...
- Miller_Rabbin大素数测试
伪素数: 如果存在和n互素的正整数a满足a^(n-1)≡1(mod n),则n是基于a的伪素数. 是伪素数但不是素数的个数是非常非常少的,所以如果一个数是伪素数,那么他几乎是素数. Miller_Ra ...
- TestNG深入理解
以下内容引自: http://blog.csdn.net/wanglha/article/details/42004695 TestNG深入理解 转载 2014年12月18日 13:56:11 参考文 ...
- testNG入门详解
TestNG 的注释: @DataProvider @ExpectedExceptions @Factory @Test @Parameters <suite name="Parame ...
- NOIP2018模板总结【数学】
质因数分解 //质因数分解 int prime[MAXN], tim[MAXN], cnt; void Divide(int N) { printf("%d = ", N); fo ...
- 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】
还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...
随机推荐
- Python 基于win32com客户端实现Excel操作
测试环境 Python 3.6.2 代码实现 非多线程场景下使用 新建并保存EXCEL import win32com.client from win32api import RGB def save ...
- 【ActiveJdbc】02
一.基本的数据库操作 数据模型层: import org.javalite.activejdbc.Model; 数据访问层: import org.javalite.activejdbc.Base; ...
- 【JS】05 DOM 文档对象模型 P2 元素的CRUD、Dom集合对象
Element & Node 元素,或者称为节点 在JS中创建一个HTML元素,但是因为没有指定在Dom对象中的节点位置,所以页面不会发生改变 var para = document.crea ...
- 如何理解计算机类论文、机器学习论文、人工智能AI论文中的“soft”和“hard”呢?
如何理解计算机类论文.机器学习论文.人工智能AI论文中的"soft"和"hard"呢? 最近在看论文中总看到带有"soft"和"h ...
- 在vscode中通过修改launch.json文件为项目添加启动参数——在launch.json文件中修改args变量
以前一直在使用pycharm,不管怎么说毕竟国内外的Python编程者大部分都更支持pycharm,并且认为pycharm是Python语言编程中最好用的编辑器,但是随着国内编程人员一茬一茬的兴起很多 ...
- nvidia显卡的售后真的是不敢要人恭维——拆机箱时误拧显卡自身挡板螺丝被拒保
事情比较简单,单位在nvidia的经销商那里购买的nvidia titan rtx显卡,保修期内坏掉,拆下来的过程中误拧了挡板的螺丝,结果被拒保,这里就是单纯的记录这件事情. 这件事确实我这方面有不对 ...
- 查看numpy中不同数据类型的表示范围
在numpy中数据类型主要可以分为int和float两个类型,查看int类型的表示范围可以使用numpy.iinfo,查看float类型的表示范围可以使用numpy.finfo . 例子: impo ...
- 白鲸开源 X SelectDB 金融大数据联合解决方案公布!从源头解决大数据开发挑战
业务挑战与痛点 随着互联网技术的发展.云计算技术的成熟.人工智能技术的兴起和数字化经济的崛起,数据已成为企业的核心资产.在金融行业中,数字化已成为了支撑各类业务场景的核心力量,包括个人理财.企业融资. ...
- Lucas-Washburn + Cassie-Baxter
如果粉末间隙内壁的表面能随着润湿而降低,则液体会向管内上升渗入(\(\gamma_{\text{SL}}<\gamma_{\text{SO}}\)). 考虑液体上升的驱动力来自于附加压力,则由弯 ...
- 基于donetcore/CAP实现分布式事务一致性
官网:https://cap.dotnetcore.xyz 相关介绍 CAP 是一个EventBus,同时也是一个在微服务或者SOA系统中解决分布式事务问题的一个框架.它有助于创建可扩展,可靠并且易于 ...