[WC2006] 水管局长 - Link Cut Tree
离线后逆序处理所有操作,那么就变成了加边询问,根据MST的性质,显然维护MST询问链上max即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000000;
int n,m,q,t1,t2,t3,t4;
struct Edge {
int u,v,w,f;
} e[N];
struct Operating {
int o,p,q;
} op[N];
struct LinkCutTree {
int top, q[N], ch[N][2], fa[N], rev[N], mx[N], mp[N], val[N];
inline void pushup(int x) {
mx[0]=mp[0]=0;
mx[x] = max(max(mx[ch[x][0]],mx[ch[x][1]]),val[x]);
if(mx[x] == mx[ch[x][0]])
mp[x]=mp[ch[x][0]];
if(mx[x] == mx[ch[x][1]])
mp[x]=mp[ch[x][1]];
if(mx[x] == val[x])
mp[x]=x;
}
inline void pushdown(int x) {
if(!rev[x])
return;
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}
inline bool isroot(int x) {
return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;
}
inline void rotate(int p) {
int q=fa[p], y=fa[q], x=ch[fa[p]][1]==p;
ch[q][x]=ch[p][x^1];
fa[ch[q][x]]=q;
ch[p][x^1]=q;
fa[q]=p;
fa[p]=y;
if(y)
if(ch[y][0]==q)
ch[y][0]=p;
else if(ch[y][1]==q)
ch[y][1]=p;
pushup(q);
pushup(p);
}
inline void splay(int x) {
q[top=1]=x;
for(int i=x; !isroot(i); i=fa[i])
q[++top]=fa[i];
for(int i=top; i; i--)
pushdown(q[i]);
for(; !isroot(x); rotate(x))
if(!isroot(fa[x]))
rotate((ch[fa[x]][0]==x)==(ch[fa[fa[x]]][0]==fa[x])?fa[x]:x);
}
void access(int x) {
for(int t=0; x; t=x,x=fa[x])
splay(x),ch[x][1]=t,pushup(x);
}
void makeroot(int x) {
access(x);
splay(x);
rev[x]^=1;
}
int find(int x) {
access(x);
splay(x);
while(ch[x][0])
x=ch[x][0];
return x;
}
void split(int x,int y) {
makeroot(x);
access(y);
splay(y);
}
void cut(int x,int y) {
split(x,y);
if(ch[y][0]==x)
ch[y][0]=0, fa[x]=0;
}
void link(int x,int y) {
makeroot(x);
fa[x]=y;
}
void setval(int p,int v) {
val[p]=mx[p]=v;
mp[p]=p;
}
int queryv(int p,int q) {
split(p,q);
return mx[q];
}
int queryp(int p,int q) {
split(p,q);
return mp[q];
}
} lct;
bool check(int p,int q) {
return lct.find(p)==lct.find(q);
}
int queryv(int p,int q) {
return lct.queryv(p,q);
}
int queryp(int p,int q) {
return lct.queryp(p,q)-n;
}
void link(int i) {
lct.link(n+i,e[i].u);
lct.link(n+i,e[i].v);
}
void cut(int i) {
lct.cut(n+i,e[i].u);
lct.cut(n+i,e[i].v);
}
void add(int i) {
if(check(e[i].u,e[i].v)) {
int v=queryv(e[i].u,e[i].v), p=queryp(e[i].u,e[i].v);
if(v > e[i].w) {
cut(p);
link(i);
}
} else
link(i);
}
map <int,int> mp[N];
vector <int> vc;
signed main() {
scanf("%lld%lld%lld",&n,&m,&q);
for(int i=1; i<=m; i++) {
scanf("%lld%lld%lld",&t1,&t2,&t3);
mp[t1][t2]=i;
mp[t2][t1]=i;
e[i]=(Edge) {
t1,t2,t3,0
};
}
for(int i=1; i<=n; i++)
lct.setval(i, 0);
for(int i=1; i<=m; i++)
lct.setval(i+n, e[i].w);
for(int i=1; i<=q; i++) {
scanf("%lld%lld%lld",&t1,&t2,&t3);
if(t1==2) {
t4 = mp[t2][t3];
e[t4].f=1;
}
op[i]=(Operating) {
t1,t2,t3
};
}
reverse(op+1,op+q+1);
for(int i=1; i<=m; i++) {
if(e[i].f==0) {
add(i);
}
}
for(int i=1; i<=q; i++) {
if(op[i].o == 1) {
vc.push_back(queryv(op[i].p,op[i].q));
} else {
add(mp[op[i].p][op[i].q]);
}
}
while(vc.size()) {
printf("%lld\n",vc.back());
vc.pop_back();
}
}
[WC2006] 水管局长 - Link Cut Tree的更多相关文章
- link cut tree 入门
鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...
- BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )
离线然后就是维护加边的动态MST, Link cut tree秒掉..不过我写+调了好久...时间复杂度O(NlogN + MlogM) ------------------------------- ...
- Link Cut Tree 总结
Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...
- [BZOJ2594] [WC2006]水管局长(Kruskal+LCT)
[BZOJ2594] [WC2006]水管局长(Kruskal+LCT) 题面 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可 ...
- BZOJ2594: [Wc2006]水管局长数据加强版
题解: 裸LCT+离线+二分+MST... 代码:(几乎摘抄自hzwer) #include<cstdio> #include<cstdlib> #include<cma ...
- [bzoj2594][Wc2006]水管局长数据加强版 (lct)
论蒟蒻的自我修养T_T.. 和noi2014魔法森林基本一样...然而数据范围大得sxbk...UPD:这题如果用lct判联通的话可能会被卡到O(mlogm)..所以最好还是用并查集吧 一开始数组开太 ...
- BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 2917 Solved: 918[Submit][St ...
- BZOJ_2594_[Wc2006]水管局长数据加强版_LCT
BZOJ_2594_[Wc2006]水管局长数据加强版_LCT Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供 ...
- P4172 [WC2006]水管局长(LCT)
P4172 [WC2006]水管局长 LCT维护最小生成树,边权化点权.类似 P2387 [NOI2014]魔法森林(LCT) 离线存储询问,倒序处理,删边改加边. #include<iostr ...
随机推荐
- 大数据才是未来,Oracle、SQL Server成昨日黄花?
1. 引子**** 有人在某个专注SQL的公众号留言如下: 这个留言触碰到一个非常敏感的问题:搞关系型数据库还有前途吗?现在都2020年了,区块链正火热,AI人才已经"过剩",大数 ...
- opencv —— erode、dilate 腐蚀与膨胀
腐蚀与膨胀是形态学滤波.其中,腐蚀是最小值滤波,膨胀是最大值滤波,即分别选取内核中的最小值与最大值赋值给锚点.若内核为 N×1 或 1×N 形状,可用于横纵方向直线检测. 膨胀:dilate 函数 v ...
- Selenium实战(五)——HTML测试报告
一.概览下载与安装 HTMLTestRunner是unittest的一个扩展,可以生成易于使用的HTML测试报告.HTMLTestRunner是在BSD许可证下发布的. 下载地址:http://tun ...
- sqlserver with 递归用法
DECLARE @companyid TABLE ( [Id] [int] ); with cte as( union all select a.Id from [base].[Company] a, ...
- DFT 问答 I
Q: Boundary Scan是什么?应用场景是什么?实现的方法是什么?挑战是什么? A: Boundary Scan就是边界扫描,是由Joint Test action Group起草的规范,最初 ...
- 小白的java学习之路 “ 数组”
数组 一.什么是数组: 数组是一个变量,存储相同数据类型的一组数据 声明一个变量就是在内存空间划出一块合适的空间 声明一个数组就是在内存空间划出一串连续的空间 二.数组基本要素: 标识符:数组的名称, ...
- adb -- cannot connect to x.x.x.x:5555“由于目标计算机积极拒绝,无法连接”
原因 安卓系统未打开adb网络调试功能 通过USB方式连接到安卓系统设置即可 解决 先通过USB线连接 adb devices 能看到所连接的设备情况下 adb root 权限提权 adb shell ...
- 剑指offer-面试题11-旋转数组的最小数字-二分法
/* 题目: 把一个数组最开始的若干个元素搬到数组末尾,我们称之为数组的旋转. 输入一个递增排序的数组的旋转,输出旋转数组中的最小元素. */ /* 思路: 采用二分的方法,旋转数组实质上是上左半部分 ...
- [Python]爬取首都之窗百姓信件网址id python 2020.2.13
经人提醒忘记发网址id的爬取过程了, http://www.beijing.gov.cn/hudong/hdjl/com.web.consult.consultDetail.flow?original ...
- Java连载85-集合的Contains和Remove方法
一.包含与删除两种方法解析 1.boolean contains(Object o);判断集合中是否包含某个元素. package com.bjpowernode.java_learning; imp ...