[bzoj4524] [loj#2047] [Cqoi2016] 伪光滑数
Description
若一个大于 \(1\) 的整数 \(M\) 的质因数分解有 \(k\) 项,其最大的质因子为 \(Ak\) ,并且满足 \(Ak^K \leq N\) , \(Ak<128\) ,我们就称整数 \(M\) 为 \(N-\) 伪光滑数。现在给出 \(N\) ,求所有整数中,第 \(K\) 大的 \(N-\) 伪光滑数。
Input
只有一行,为用空格隔开的整数 \(N\) 和 \(K\)
\(2 \leq N \leq 10^18\) ,\(1 \leq K \leq 800000\),保证至少有 \(K\) 个满足要求的数
Output
只有一行,为一个整数,表示答案。
Sample Input
12345 20
Sample Output
9167
想法
目前见到的求 第 \(K\) 大/小的题大概有三种做法:
1.二分判断。
2.在 \(K\) 不太大时,可以从大到小/从小到大枚举,用数据结构维护当前最大,取出最大值后用次大值(扩展值)代替它。
3.堆的 \(K\) 路归并(我也不懂这是啥 %%%标算)
这道题中我用的是第二种做法。
首先一个性质,对于数 \(i\) ,\(i \leq Ak^k \leq N\) ,假设 \(Ak^k\) 为 \(i\) 的“特征数”
由于 \(Ak \leq 128\) , 而128以内的质数仅31个,所以 \(N\) 以内的特征数值很少
所以大体想法就是优先队列维护所有的“特征数”对应的 \(i\) 的最大值,每次取出最大,用次大替代就行了。
初始状态时每个特征数对应的最大值很好搞,就是 \(Ak^k\) (特征数本身的值)
但次大是多少呢? \(Good\) \(Question!\)
我发现次大有两种情况,一种把一个 \(Ak\) 换为 \(A_{k-1}\),一种是将某一个 \(Ax\) 换为 \(A_{x-1}\)
有点乱。
试着搞出一种扩展顺序,即“分层扩展”。
初始状态,某个特征数 \(Ak^k\) 对应的最大值是 \(k\) 个 \(Ak\) 相乘,不妨称它的层数为0
在扩展 \(Ak^k\) 时,取出一个 \(Ak\) ,换成 \(A1,A2,...,A_{k-1}\) ,即 \(Ak^{k-1} \times Ax\) ,称它们的层数为1(替换了一个 \(Ak\))
在扩展 \(AK^{k-1} \times Ax\) 时,再取出一个 \(Ak\) ,换成 \(A1,A2,...,Ax\) ,即 \(Ak^{k-2} \times Ax \times Ay\) ,称它们的层数为2(替换了两个 \(Ak\))
以此类推……
注意到每次扩展时,\(Ay \leq Ax\) ,这是为了防止同一个数,由于被换的顺序不同而被计算多次。
这样可以保证每次扩展后,该特征数的次大值都在优先队列中嘛?(注意,是“在优先队列中”,但不一定是这次扩展加进去的)
首先,显然每个数扩展出的数都比它本身小,所以对于所有可以通过这种方法扩展出、但没加到优先队列中的数,一定说明扩展出它的数没加到优先队列中或在队列中还没成为最大值,即这些数不是我要的“次大值”
而是不是所有数都可以通过这种方法扩展出呢?显然可以!
其实这就是模拟搜索吧。。。复杂度 \(O(128K)\) 可以卡过。
一些启示
\(Orz\)
分层扩展……?
要有一些顺序的思想吧,不必每次只扩展一个……?
【我也不知道哭唧唧】
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
ll n;
int k;
int p[31]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127};
struct data{
ll t;
int x,y,z; // p[x]^y,nxtmin--p[z]
data() { t=0; x=y=z=0; }
data(ll a,int b,int c,int d) { t=a; x=b; y=c; z=d; }
bool operator < (const data &b) const{ return t<b.t; }
};
priority_queue<data> q;
int main()
{
scanf("%lld%d",&n,&k);
ll x;
for(int i=0;i<31;i++){
x=1;
for(int j=1;1ll*x*p[i]<=n;j++){
x*=p[i];
q.push(data(x,i,j,i-1));
}
}
data tmp;
while(k--){
tmp=q.top(); q.pop();
if(tmp.y>1){
for(int i=tmp.z;i>=0;i--)
q.push(data(tmp.t/p[tmp.x]*p[i],tmp.x,tmp.y-1,i));
}
}
printf("%lld\n",tmp.t);
return 0;
}
[bzoj4524] [loj#2047] [Cqoi2016] 伪光滑数的更多相关文章
- 【BZOJ4524】[Cqoi2016]伪光滑数 堆(模拟搜索)
[BZOJ4524][Cqoi2016]伪光滑数 Description 若一个大于1的整数M的质因数分解有k项,其最大的质因子为Ak,并且满足Ak^K<=N,Ak<128,我们就称整数M ...
- @bzoj - 4524@ [Cqoi2016]伪光滑数
目录 @description@ @solution@ @version - 1@ @version - 2@ @accepted code@ @version - 1@ @version - 2@ ...
- [CQOI2016]伪光滑数
题目描述 若一个大于1的整数M的质因数分解有k项,其最大的质因子为Ak,并且满足Ak^K<=N,Ak<128,我们就称整数M为N-伪 光滑数.现在给出N,求所有整数中,第K大的N-伪光滑数 ...
- BZOJ4524 CQOI2016伪光滑数(堆)
对于每个质数求出其作为最大质因子时最多能有几个质因子,开始时将这些ak1~akmaxk扔进堆.考虑构造方案,使得每次取出最大值后,最大质因子.质因子数均与其相同且恰好比它小的数都在堆里.类似暴搜,对于 ...
- BZOJ4524 [Cqoi2016]伪光滑数
BZOJ上的题面很乱,这里有一个题面. 题解: 正解是可持久化可并堆+DP,可惜我不会... 但暴力也可过这道题. 先在不超过N的前提下,在大根堆里加入每个质数的J次方,1<=j, 然后就可以发 ...
- Bzoj 4524 [Cqoi2016]伪光滑数(堆)
题面 题解 先筛出$<128$的质数,很少,打个表即可 然后钦定一个质数最大,不断替换即可(丢进大根堆里面,然后取出一个,替换在丢进去即可) 具体来说,设一个四元组$[t,x,y,z]$表示当前 ...
- 【BZOJ-4524】伪光滑数 堆 + 贪心 (暴力) [可持久化可并堆 + DP]
4524: [Cqoi2016]伪光滑数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 183 Solved: 82[Submit][Status] ...
- 2021.08.01 P4359 伪光滑数(二叉堆)
2021.08.01 P4359 伪光滑数(二叉堆) [P4359 CQOI2016]伪光滑数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 若一个大于 11 的整数 MM ...
- Loj 2047 伪光滑数
Loj 2047 伪光滑数 正解较复杂,但这道题其实可以通过暴力解决. 预处理出 \(128\) 内的所有质数,把 \(n\) 内的 \(prime[i]^j\) 丢进堆中,再尝试对每个数变形,除一个 ...
随机推荐
- BAT 脚本判断当前系统是 x86 还是 x64 系统
本文告诉大家在写 BAT 脚本的时候,如何判断当前的系统是 32 位系统的还是 64 位系统 通过注册表进行判断方法 @echo OFF reg Query "HKLM\Hardware\D ...
- ZR并查集专题
ZR并查集专题 并查集,作为一个基础算法,对于初学者来说,下面的代码是维护连通性的利器 return fa[x] == x ? x : fa[x] = getf(fa[x]); 所以,但是这对并查集的 ...
- vue-learning:4-template-v-if-and-v-show
控制元素可见性的指令 v-if 和 v-show v-if v-else v-else-if :多重判断 template :分组渲染包裹元素 key:管理可复用元素 v-show v-if与v-sh ...
- dotnet 动态代理魔法书
看到标题的小伙伴是不是想知道什么是魔法书,如果你需要写一段代码,这段代码是在做神奇的业务,只有你查询到了魔法书你才能找到这个对象,同时你还需要实现自己的接口,通过自己实现的接口调用才能用到有趣的方法 ...
- codeforces 677D(分层图dp)
Codeforces 677D 传送门:https://codeforces.com/contest/677/problem/D 题意: 给你一个n*m的方格图,每个点有一个权值val,现在要求你从坐 ...
- 前端工具--利用Adblock Plus阻止js执行
今天遇到个问题:需要阻止页面某个js的运行 效果达到
- #mysql查询特定数据库中的所有表名
#mysql查询特定数据库中的所有表名select table_namefrom information_schema.tableswhere table_schema='smbms' and tab ...
- 激励函数 (Activation)
softplus是有关概率的巴拉巴拉? Torch 中的激励函数有很多, 不过我们平时要用到的就这几个. relu, sigmoid, tanh, softplus. 那我们就看看他们各自长什么样啦. ...
- 【重学Node.js 第4篇】实现一个简易爬虫&启动定时任务
实现一个简易爬虫&启动定时任务 课程介绍看这里:https://www.cnblogs.com/zhangran/p/11963616.html 项目github地址:https://gith ...
- saltstack操作
使用分组 修改minon的ID,做一个标识 [root@node2 ~]# vim /etc/salt/minionmaster: 172.25.254.130 id: web1 #node2[roo ...