题解

可持久化可并堆

用\(f[i,j]\)表示最大的质数标号为i,然后有j个质数乘起来

用\(g[i,j]\)表示\(\sum_{k = 1}^{i}f[k,j]\)

转移是

\(f[i,j] = \sum_{k= 1}^{j} g[i - 1,j - k] * p_{i}^{k}\)

\(g[i,j] += f[i,j]\)

这就要资瓷两个集合的合并了

可是集合显然非常大,我们可以用可持久化来帮助完成这件事,就完成了

代码

#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define MAXN 1000005
#define pb push_back
#define mp make_pair
#define eps 1e-8
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int64 N;
int K,prime[105],tot;
bool nonprime[205];
int64 pw[105];
struct node {
node *lc,*rc;
int64 mul,val;
int dis;
}pool[17000000],*tail = pool;
struct set_node {
int64 val;node *rt;
set_node(){}
set_node(int64 _v,node *r) {
val = _v;rt = r;
}
friend bool operator < (const set_node &a,const set_node &b) {
return a.val > b.val;
}
friend bool operator == (const set_node &a,const set_node &b) {
return a.val == b.val && a.rt == b.rt;
}
};
node *g[105],*f[105];
set<set_node > S;
node *Newnode(int64 v) {
node *res = tail++;
res->mul = 1;res->val = v;
res->lc = res->rc = NULL;
res->dis = 0;
return res;
}
int getdist(node *p) {
return p ? p->dis : -1;
}
node* addlazy(node *u,int64 val) {
if(!u) return NULL;
node *res = tail++;
*res = *u;
res->val *= val;
res->mul *= val;
return res;
}
void push_down(node *&u) {
if(u->mul != 1) {
u->lc = addlazy(u->lc,u->mul);
u->rc = addlazy(u->rc,u->mul);
u->mul = 1;
}
}
node *Merge(node *A,node *B) {
if(!A) return B;
if(!B) return A;
if(A->val < B->val) swap(A,B);
push_down(A);
node *res = tail++;
*res = *A;
res->rc = Merge(A->rc,B);
if(getdist(res->rc) > getdist(res->lc)) swap(res->lc,res->rc);
res->dis = getdist(res->rc) + 1;
return res;
}
void Solve() {
read(N);read(K);
for(int i = 2 ; i <= 128 ; ++i) {
if(!nonprime[i]) {
prime[++tot] = i;
for(int j = 2 ; j <= 128 / i ; ++j) {
nonprime[i * j] = 1;
}
}
}
for(int i = 0 ; i <= 100 ; ++i) g[i] = NULL;
g[0] = Newnode(1);
for(int i = 1 ; i <= tot ; ++i) {
int cnt = 0;int64 t = N;
while(t >= prime[i]) {t /= prime[i];++cnt;}
pw[0] = 1;
for(int k = 1 ; k <= cnt ; ++k) pw[k] = pw[k - 1] * prime[i];
for(int k = 1 ; k <= cnt ; ++k) {
f[k] = NULL;
for(int h = 1 ; h <= k ; ++h) {
f[k] = Merge(f[k],addlazy(g[k - h],pw[h]));
}
}
for(int k = 1 ; k <= cnt ; ++k) g[k] = Merge(g[k],f[k]);
}
node *rt = NULL;
for(int i = 1 ; i <= 100 ; ++i) rt = Merge(rt,g[i]);
S.insert(set_node(rt->val,rt));
for(int i = 1 ; i < K ; ++i) {
set_node p = *S.begin();
S.erase(S.begin());
push_down(p.rt);
if(p.rt->lc) S.insert(set_node(p.rt->lc->val,p.rt->lc));
if(p.rt->rc) S.insert(set_node(p.rt->rc->val,p.rt->rc));
while(S.size() > K - i) S.erase(--S.end());
}
out((*S.begin()).val);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【LOJ】#2047. 「CQOI2016」伪光滑数的更多相关文章

  1. loj #2044. 「CQOI2016」手机号码

    #2044. 「CQOI2016」手机号码 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  2. Loj 2047 伪光滑数

    Loj 2047 伪光滑数 正解较复杂,但这道题其实可以通过暴力解决. 预处理出 \(128\) 内的所有质数,把 \(n\) 内的 \(prime[i]^j\) 丢进堆中,再尝试对每个数变形,除一个 ...

  3. 【BZOJ4524】[Cqoi2016]伪光滑数 堆(模拟搜索)

    [BZOJ4524][Cqoi2016]伪光滑数 Description 若一个大于1的整数M的质因数分解有k项,其最大的质因子为Ak,并且满足Ak^K<=N,Ak<128,我们就称整数M ...

  4. @bzoj - 4524@ [Cqoi2016]伪光滑数

    目录 @description@ @solution@ @version - 1@ @version - 2@ @accepted code@ @version - 1@ @version - 2@ ...

  5. 【BZOJ-4524】伪光滑数 堆 + 贪心 (暴力) [可持久化可并堆 + DP]

    4524: [Cqoi2016]伪光滑数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 183  Solved: 82[Submit][Status] ...

  6. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  7. LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree

    2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  8. 2021.08.01 P4359 伪光滑数(二叉堆)

    2021.08.01 P4359 伪光滑数(二叉堆) [P4359 CQOI2016]伪光滑数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 若一个大于 11 的整数 MM ...

  9. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

随机推荐

  1. 疯狂Android讲义

    1 Android应用和开发环境2 Android应用的界面编程3 Android的事件处理4 Activity Fragment5 Intent IntentFilter6 Android应用的资源 ...

  2. Java基础-程序流程控制第一弹(分支结构/选择结构)

    Java基础-程序流程控制第一弹(分支结构/选择结构) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.if语句 1>.if语句的第一种格式 if(条件表达式){ 语句体: ...

  3. 不忘初心,方得始终——NOIP2016前的感悟

    不忘初心,方得始终 袛园精舍钟声响,奏诸世事本无常.沙罗双树失花色,盛者转衰如沧桑.骄者难久,恰如春宵一梦.猛者遂灭,好似风前之尘.    ——题记   人生中最令人恐惧的恐怕就是选择了,现在的你拥有 ...

  4. 2016-2017-2 《Java程序设计》第七周学习总结

    20155313 2016-2017-2 <Java程序设计>第七周学习总结 第十二章 Lambda 12.1认识Lambda语法 12.1.1Lambda语法概览 在java中引入了La ...

  5. 20155303 2016-2017-2 《Java程序设计》第七周学习总结

    20155303 2016-2017-2 <Java程序设计>第七周学习总结 教材学习中的问题和解决过程 『问题一』:SimpleDateFormat中每个字符的含义都是什么? 『问题一解 ...

  6. Vue 表格内容根据后台返回状态位填充文字

    本文地址:http://www.cnblogs.com/veinyin/p/8534365.html  Vue 做表格时我们常用的就是 v-for ,直接把 prop 绑定上去,但是如果表格内容需要我 ...

  7. HDU 3535 AreYouBusy (混合背包之分组背包)

    题目链接 Problem Description Happy New Term! As having become a junior, xiaoA recognizes that there is n ...

  8. 2016.6.17——Remove Duplicates from Sorted Array

    Remove Duplicates from Sorted Array 本题收获: 1.“删除”数组中元素 2.数组输出 题目: Given a sorted array, remove the du ...

  9. Next Permutation & Previous Permutation

    Next Permutation Given a list of integers, which denote a permutation. Find the next permutation in ...

  10. android开发中常用的快捷键

    Eclipse快捷键-方便查找,呵呵,记性不好 行注释/销注释 Ctrl+/  块注释/销注释/XML注释 Ctrl+Shift+/   Ctrl+Shift+\查找 查找替换 Ctrl+H  Ctr ...