bzoj4933: 妙
Description
Input
Output
只需要一个维护可重集合的数据结构,支持可持久化地合并,对一个集合中所有数加,最后能查询一次前k小,就可以按类似通常树形依赖背包的处理方法求解。
这里使用可持久化多叉堆实现,其中用可持久化左偏树维护多叉堆每个点的多个孩子。
对于合并操作直接把 堆顶元素大的堆 作为 堆顶元素小的堆 的 孩子,插进维护孩子的左偏树上,因此保证了每颗左偏树大小在O(n),而不是直接合并的O(2n)
对于加法可以直接打标记实现
最后求前k小只需把这个堆当成一棵普通的树,跑一次dijkstra
总时间复杂度O(nlogn),常数很大
#include<bits/stdc++.h>
typedef long long i64;
const int N=1e5+;
struct node;
node*cpy(node*);
node*new_node();
struct node{
node*lc,*rc,*mc;
i64 v,a;
int h;
node*add(i64 x);
node*dn();
void up();
}*mem,*mp,*nil;
node*node::add(i64 x){
if(this==nil)return this;
node*w=new_node();
*w=(node){lc,rc,mc,v+x,a+x,h};
return w;
}
node*node::dn(){
if(this==nil)return this;
node*w=cpy(this);
if(a){
w->lc=lc->add(a);
w->rc=rc->add(a);
w->mc=mc->add(a);
w->a=;
}
return w;
}
void node::up(){
if(lc->h<rc->h)std::swap(lc,rc);
h=rc->h+;
}
node*cpy(node*w){
node*u=new_node();
*u=*w;
return u;
}
node*new_node(){
if(mem==mp)mem=new node[N],mp=mem+N;
return --mp;
}
node*mg(node*a,node*b){
if(a==nil)return b;
if(b==nil)return a;
if(a->v>b->v)std::swap(a,b);
a=a->dn();
a->rc=mg(a->rc,b);
a->up();
return a;
}
node*heap_mg(node*a,node*b){
if(a->v>b->v)std::swap(a,b);
a=a->dn();
a->mc=mg(a->mc,b->dn());
return a;
}
std::vector<int>e[N];
int n,k,v0[N];
node*f[N];
void dfs(int w,int pa){
f[w]=f[w]->add(v0[w]);
for(int i=;i<e[w].size();++i){
int u=e[w][i];
if(u==pa)continue;
f[u]=f[w];
dfs(u,w);
f[w]=heap_mg(f[w],f[u]);
}
}
char buf[N*],*ptr=buf-,ob[N*],*op=ob;
int _(){
int x=,f=,c=*++ptr;
while(c<)c=='-'?f=-:,c=*++ptr;
while(c>)x=x*+c-,c=*++ptr;
return x*f;
}
void pr(i64 x){
if(x<)x=-x,*op++='-';
int ss[],sp=;
do ss[++sp]=x%;while(x/=);
while(sp)*op++=ss[sp--]+;
*op++=;
}
struct cmp{bool operator()(node*a,node*b){return a->v>b->v;}};
std::priority_queue<node*,std::vector<node*>,cmp>q;
void push(node*w){
if(w!=nil)q.push(w);
}
int main(){
fread(buf,,sizeof(buf),stdin);
nil=new_node();
*nil=(node){nil,nil,,,-};
n=_(),k=_();
for(int i=;i<=n;++i)v0[i]=_();
for(int i=,a,b;i<n;++i){
a=_(),b=_();
e[a].push_back(b);
e[b].push_back(a);
}
*(f[]=new_node())=(node){nil,nil,nil,,,};
dfs(,);
push(f[]);
while(q.size()&&k){
--k;
node*w=q.top();q.pop();
w=w->dn();
pr(w->v);
push(w->lc);
push(w->rc);
push(w->mc);
}
fwrite(ob,,op-ob,stdout);
return ;
}
bzoj4933: 妙的更多相关文章
- 【CSS进阶】伪元素的妙用--单标签之美
最近在研读 <CSS SECRET>(CSS揭秘)这本大作,对 CSS 有了更深层次的理解,折腾了下面这个项目: CSS3奇思妙想 -- Demo (请用 Chrome 浏览器打开,非常值 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- JavaScript的妙与乐(一)之 函数优化
JavaScript的妙与乐系列文章主要是展示一些JavaScript上面比较好玩一点的特性和一些有用的技巧,里面很多内容都是我曾经在项目中使用过的一些内容(当然,未必所有技巧的使用频率都很高^_^) ...
- Promise的前世今生和妙用技巧
浏览器事件模型和回调机制 JavaScript作为单线程运行于浏览器之中,这是每本JavaScript教科书中都会被提到的.同时出于对UI线程操作的安全性考虑,JavaScript和UI线程也处于同一 ...
- 【CSS进阶】伪元素的妙用2 - 多列均匀布局及title属性效果
最近无论是工作还是自我学习提升都很忙,面对长篇大论的博文总是心有余而力不足,但又不断的接触学习到零碎的但是很有意义的知识点,很想分享给大家,所以本篇可能会很短. 本篇接我另一篇讲述 CSS 伪元素的文 ...
- 不太被人提起的%%lockres%%的妙用
%%lockres%% 这个值似乎很少被大家提到,甚至微软在官方文档中. 它返回是一个Hash Value,看乎这个值没什么用. 后来在实践也有它的妙用之处,比如在出现性能问题如LOCK时,一般先通过 ...
- 【优雅代码】深入浅出 妙用Javascript中apply、call、bind
这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我 ...
- 【javascript 技巧】Array.prototype.slice的妙用
Array.prototype.slice的妙用 开门见山,关于Array 的slice的用法可以参考这里 http://www.w3school.com.cn/js/jsref_slice_arra ...
- EF6 Power Tools的妙用和问题
环境:vs2013+EF:6.1.3.0+Power Tools:Beta 4 power tools:是一个反向工程,在已有数据库的情况下,可以利用它生成Code Frist模式的代码. 问题: 它 ...
随机推荐
- poj 2253——Frogger
这个题一开始不知道咋做,但是大致有点意思.后来还是借鉴了题解发现可以用dijkstra,不太理解.但是在最后自己推的时候突然理解了. dijkstra应该也算是动态规划.我们用dis[i]数组作为青蛙 ...
- P1005 矩阵取数游戏(动态规划+高精度)
题目链接:传送门 题目大意: 给定长度为m的数列aj,每次从两端取一个数,得到2k * aj的价值(k为当前的次数,从1开始到m),总共有n行这样的数列,求最大价值总和. 1 ≤ n, m ≤ 80, ...
- Python语言规范
Lint 对你的代码运行pylint 定义: pylint是一个在Python源代码中查找bug的工具. 对于C和C++这样的不那么动态的(译者注: 原文是less dynamic)语言, 这些bug ...
- redis 部署相关
★ 启动: 配置好环境变量后:打开一个cmd窗口,执行redis-server.exe就可以启动redis了. https://blog.csdn.net/weixin_42423819/articl ...
- Go Example--map
package main import "fmt" func main() { //初始化map make(map[类型][类型]) m:= make(map[string]int ...
- gdb入门
下面是我自己写的一个测试用例 a.c #include<stdio.h> int add(int a,int b){ return a+b; } int main(){ int n=add ...
- Java中的包学习笔记
一.总结 1.引入包的概念的原因和包的作用比如有多个人开发一个大型程序,A定义了一个Math.java类,B也定义了一个Math.java类,它们放在不同目录,使用的时候也是用目录来区分,包实际上就是 ...
- MySQL Execution Plan--数据排序操作
MySQL数据排序 MySQL中对数据进行排序有三种方式:1.常规排序(双路排序)2.优化排序(单路排序)3.优先队列排序 优先队列排序使用对排序算法,利用堆数据结构在所有数据中取出前N条记录. 常规 ...
- 电脑上不安装Oracle时,C# 调用oracle数据库,Oracle客户工具 【转载】
http://www.cnblogs.com/jiekzou/p/5047850.html Oracle的安装包通常都比较大,安装又比较费时,而且如果安装过程中不幸出错,各种蛋疼,即便是安装过N遍的老 ...
- flutter 控制台快捷键