弱省互测#1 t3
题意
给出一棵n个点的树,求包含1号点的第k小的连通块权值和。(\(n<=10^5\))
分析
k小一般考虑堆...
题解
堆中关键字为\(s(x)+min(a)\),其中\(s(x)\)表示\(x\)状态的权值和,\(min(a)\)表示\(x\)状态相邻的不在\(x\)里的的点的最小权值。
每一次从堆中弹出最小的,然后用这个来拓展。
可以证明,这样第\(k\)次弹出来的状态\(x \cup \\{ a \\}\)就是\(k\)小的。
证明很简单,堆中的都是待拓展状态,每一次取出来\(x \cup \\{ a \\}\)的将来再也不会有状态的权值和小于这个状态。
维护相邻的点我们可以用可持久化堆搞。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MX=8000005; //超过这个数这份代码别想活了【捂脸熊
struct node *null;
struct node {
node *c[2];
int x, w, s;
void up() { s=1+c[0]->s+c[1]->s; if(c[0]->s<c[1]->s) swap(c[0], c[1]); }
}pool[MX], *iT=pool;
int cc=2;
node *newnode() {
node *x=iT++; ++cc; if(cc>=MX) { puts("err"); exit(0); }
x->c[0]=x->c[1]=null; x->x=-1; x->w=0; x->s=0;
return x;
}
void cpy(node *x, node *y) {
x->x=y->x; x->w=y->w; x->s=y->s;
x->c[0]=y->c[0]; x->c[1]=y->c[1];
}
void init() {
null=iT++;
null->c[0]=null->c[1]=null;
null->x=0; null->w=0; null->s=0;
}
node *merge(node *l, node *r) {
if(l==null) return r;
if(r==null) return l;
node *x=newnode();
if(l->w<=r->w) { cpy(x, l); x->c[1]=merge(x->c[1], r); }
else { cpy(x, r); x->c[1]=merge(x->c[1], l); }
x->up();
return x;
}
node *ins(node *x, node *y) {
if(x==null) return y;
node *p=x;
if(y->w<=x->w) p=y, p->c[0]=x;
else x->c[1]=ins(x->c[1], y);
p->up();
return p;
}
node *ins(node *x, int id, int w, int flag=1) {
node *y=newnode(); y->x=id; y->w=w; y->s=1;
return flag?merge(x, y):ins(x, y);
}
node *del(node *x) { return merge(x->c[0], x->c[1]); }
struct ip {
node *x; ll sum;
bool operator<(const ip &a) const { return sum<a.sum; }
};
multiset<ip> q;
const int N=100005;
int ihead[N], f[N], cnt, n, K;
struct E { int next, to, w; }e[N<<1];
void add(int x, int y, int w) {
e[++cnt]=(E){ihead[x], y, w}; ihead[x]=cnt;
e[++cnt]=(E){ihead[y], x, w}; ihead[y]=cnt;
}
node *root[N];
int main() {
init();
scanf("%d%d", &n, &K);
for(int i=2; i<=n; ++i) {
int w;
scanf("%d%d", &f[i], &w);
add(i, f[i], w);
}
node *rt=null;
for(int x=1; x<=n; ++x) {
root[x]=null;
for(int i=ihead[x]; i; i=e[i].next) if(e[i].to!=f[x])
root[x]=ins(root[x], e[i].to, e[i].w, 0);
}
root[n+1]=ins(null, 1, 0, 0);
q.insert((ip){root[n+1], 0});
ll ans=0; int cnt=0; ip t;
multiset<ip>::iterator it;
while(1) {
if(q.size()==0) break;
it=q.begin(); q.erase(it);
t=*it;
ans=t.sum;
node *now=t.x;
if(now==null) continue;
rt=del(now); if(rt!=null) q.insert((ip){rt, t.sum-now->w+rt->w});
rt=merge(rt, root[now->x]);
q.insert((ip){rt, t.sum+rt->w});
++cnt; if(cnt==K) { ans=t.sum; break; }
if((int)q.size()>K) { it=q.end(); q.erase(--it); }
}
printf("%lld\n", ans%998244353);
return 0;
}
弱省互测#1 t3的更多相关文章
- 弱省互测#2 t3
题意 给出\(n\)个01字节和\(m\)个01字节,要求用后者去匹配前者,两个串能匹配当且仅当除了每个字节末位不同,其他位都要相同.问匹配后者至少有多少个末位不同.(\(1 \le m \le n ...
- 弱省互测#0 t3
Case 1 题意 要求给出下面代码的答案然后构造输入. 给一个图, n 个点 m 条边 q 次询问,输出所有点对之间最大权值最小的路径. 题解 把每一个询问的输出看成一条边,建一棵最小生成树. Ca ...
- 【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)
Description 给定一颗 \(n\) 个点的树,带边权. 你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...
- 弱省互测#2 t2
题意 给两个树,大小分别为n和m,现在两棵树各选一些点(包括1),使得这棵树以1号点为根同构(同构就是每个点的孩子数目相同),求最大的同构树.(n, m<=500) 分析 我们从两棵树中各取出一 ...
- 弱省互测#0 t2
题意 给定两个字符串 A 和 B,求下面四个问题的答案: 1.在 A 的子串中,不是 B 的子串的字符串的数量. 2.在 A 的子串中,不是 B 的子序列的字符串的数量. 3.在 A 的子序列中,不是 ...
- 弱省互测#0 t1
题意 给一个\(N \times M\)的01网格,1不能走,从起点\((1, 1)\)走到\((N, M)\),每次只能向下或向右走一格,问两条不相交的路径的方案数.(n, m<=1000) ...
- 【loj2461】【2018集训队互测Day 1】完美的队列
#2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...
- 【2018集训队互测】【XSY3372】取石子
题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...
- 洛谷 P4463 - [集训队互测 2012] calc(多项式)
题面传送门 & 加强版题面传送门 竟然能独立做出 jxd 互测的题(及其加强版),震撼震撼(((故写题解以祭之 首先由于 \(a_1,a_2,\cdots,a_n\) 互不相同,故可以考虑求出 ...
随机推荐
- 耿丹CS16-2班助教总结
Deadline: 2016-1-7 11:59pm 开篇有言 --又是一年末,不似风光,却添风霜,顶霾前进,踽踽独行,可乎? 助教那些事儿 助教这份工作是之前就担任过的,很羞愧,当时才担任了几天就撒 ...
- airflow 部署
环境 : ubuntu 14.04 LTS python 2.7 script: 设置环境变量: export AIRFLOW_HOME=~/airflow 安装相关依赖包: sudo apt-get ...
- From 202.97.60.193 icmp_seq=48 Time to live exceeded
从浙江某电信ip的服务器上 ping 大陆外某个外网地址不通,报如下信息: From 202.97.60.193 icmp_seq=48 Time to live exceeded google,百度 ...
- java的关闭钩子(Shutdown Hook)
Runtime.getRuntime().addShutdownHook(shutdownHook); 这个方法的含义说明: 这个方法的意思就是在jvm中增加一个关闭的钩子,当jv ...
- 设计模式--适配器模式Adapter(结构型)
一.适配器模式 适配器模式的主要作用是在新接口和老接口之间进行适配.将一个类的接口转换成客户端期望的另外一个接口.其实适配器模式有点无赖之举,在前期设计的时候,我们就不应该考虑适配器模式,而应该通过重 ...
- IIS性能提升
1. 调整IIS 7应用程序池队列长度 由原来的默认1000改为65535. IIS Manager > ApplicationPools > Advanced Settings Queu ...
- Shell 脚本实现随机抽取班级学生
#/bin/bash function rand(){ min=$ max=$(($-$min+)) num=$(date +%s%N) echo $(($num%$max+$min)) } rnd= ...
- KVO __ 浅谈
KVO :Key-Value Observing 它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了. ...
- 鱼搜_鱼搜官网_鱼搜搜索_http://www.7yusou.com
收集了N多视频小站,然后花了3天时间弄了一个鱼搜搜索网站.欢迎大家访问哟. http://www.7yusou.com
- [UWP]UWP中获取联系人/邮件发送/SMS消息发送操作
这篇博客将介绍如何在UWP程序中获取联系人/邮件发送/SMS发送的基础操作. 1. 获取联系人 UWP中联系人获取需要引入Windows.ApplicationModel.Contacts名称空间. ...