OVOO
题目描述:
$zhx$有一个棵$n$个点的树,每条边有个权值。
定义一个连通块为一个点集与使这些点连通的所有边(这些点必须连通)。
定义一个连通块的权值为这个连通块的边权和(如果一个连通块只包含一个点,那么它的权值为$0$)。
$zhx$想找一个包含$1$号点的连通块送给他的妹子,所以他希望你求出包含$1$号点的所有连通块中权值第$k$小的连通块的权值。
题解:
非常裸的可持久化可并堆。
经典的$k$短路要求维护绕多远+终点,而它维护总边权+可选边集。
维护边集时需要可持久化可并堆。
还是经典操作,要么扔掉上一条边换上次优,要么在边集中找一个最优然后更新边集。
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ;
const int MOD = ;
const int M = *N;
typedef long long ll;
template<typename T>
inline void read(T&x)
{
T f = ,c = ;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){c=c*+ch-'';ch=getchar();}
x = f*c;
}
int n,k,rt[N],wy[M];
ll ww[M];
struct edc
{
int x;
ll d;
edc(){}
edc(int x,ll d):x(x),d(d){}
friend bool operator < (edc a,edc b)
{
return a.d>b.d;
}
}tp;
int tot,tw;
struct node
{
int ls,rs,dis,tl;
ll v;
}p[M];
int merge1(int x,int y)
{
if(!x||!y)return x+y;
if(p[x].v>p[y].v)swap(x,y);
p[x].rs = merge1(p[x].rs,y);
if(p[p[x].ls].dis<p[p[x].rs].dis)swap(p[x].ls,p[x].rs);
p[x].dis=p[p[x].rs].dis+;
return x;
}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(p[x].v>p[y].v)swap(x,y);
int u = ++tot;
p[u] = p[x],p[u].rs = merge(p[u].rs,y);
if(p[p[u].ls].dis<p[p[u].rs].dis)swap(p[u].ls,p[u].rs);
p[u].dis = p[p[u].rs].dis+;
return u;
}
priority_queue<edc>q;
ll ans;
int main()
{
freopen("tt.in","r",stdin);
read(n),read(k);
for(int f,w,i=;i<n;i++)
{
read(f),read(w);
p[++tot].dis=,p[tot].tl=i+,p[tot].v=w;
rt[f] = merge1(rt[f],tot);
}
k--;
tw=;
ww[tw] = p[rt[]].v;
wy[tw] = rt[];
q.push(edc(,ww[]));
while(k&&!q.empty())
{
tp = q.top();
q.pop();
k--;
int u = tp.x;
ans = ww[u];
if(!k)break;
int ls = p[wy[u]].ls,rs = p[wy[u]].rs;
int tmp = merge(ls,rs);
if(tmp)
{
tw++;
ww[tw] = ww[u]-p[wy[u]].v+p[tmp].v;
wy[tw] = tmp;
q.push(edc(tw,ww[tw]));
}
tw++;
wy[tw] = merge(tmp,rt[p[wy[u]].tl]);
ww[tw] = ww[u]+p[wy[tw]].v;
if(wy[tw])q.push(edc(tw,ww[tw]));
}
printf("%lld\n",ans%MOD);
return ;
}
OVOO的更多相关文章
- 【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)
Description 给定一颗 \(n\) 个点的树,带边权. 你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...
- IntelliJ IDEA sass环境配置及常见报错处理
1.下载安装ruby,网上教程很多的,安装完之后在命令行输入ruby -v检查一下是否安装成功了.(注意安装的时候要勾选第二项).
- GitHub创建个人主页
在GitHub,一个项目对应唯一的Git版本库,创建一个新的版本库就是创建一个新的项目.访问仪表板(Dashboard)页面,如图3-1,可以看 到关注的版本库中已经有一个,但自己的版本库为零.在显示 ...
- 面向初学者的指南:创建时间序列预测 (使用Python)
https://blog.csdn.net/orDream/article/details/100013682 上面这一篇是对 https://www.analyticsvidhya.com/blog ...
随机推荐
- 如何修改hosts文件并生效
hosts文件位置C:\Windows\System32\drivers\etc(可以建立一个.bat 的文件把(start "" C:\Windows\System32\driv ...
- chrome调试中resource改到application中了
如题,看视频的时候发现在resource下面查看cookie,但是自己试的时候发现没有了这个工具, google之后发现原来该位置了
- 一类 O(1) 算法的总结
这里要注意一下, 一部分 O(1) 算法是需要 \(O(n)\) 或者 \(O(\sqrt n)\) 预处理的... 1. O(1) 求 1~n 的异或和: inline int calc(R int ...
- Django Views: Dynamic Content
世味年来薄似纱,谁令骑马客京华. 小楼一夜听春雨,深巷明朝卖杏花. 矮纸斜行闲作草,晴窗细乳戏分茶. 素衣莫起风尘叹,犹及清明可到家. Your Second View: Dynamic Conten ...
- .Net开发人员必备工具下载
.Net开发人员必备工具下载 本人亲测下载地址: Win8.1破解工具下载: http://pan.baidu.com/s/1eQf2UiQ 可激活版本 Windows Vista Busines ...
- Linux 导出Okular 编辑的pdf批注
1.环境 ubuntu 14.04 LTS Okular Version 0.19.3 Using KDE Development Platform 4.13.3 2.方法 2.1只导出批注,不改变p ...
- h5-16-插入SVG图片
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Java三大特性之---封装
封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保 ...
- 152 Maximum Product Subarray 乘积最大子序列
找出一个序列中乘积最大的连续子序列(该序列至少包含一个数).例如, 给定序列 [2,3,-2,4],其中乘积最大的子序列为 [2,3] 其乘积为 6.详见:https://leetcode.com/p ...
- K-th Number 线段树的区间第K大
http://poj.org/problem?id=2104 由于这题的时间限制不紧,所以用线段树水一水. 每个节点保存的是一个数组. 就是对应区间排好序的数组. 建树的时间复杂度需要nlogn 然后 ...