P3206 [HNOI2010]城市建设 [线段树分治+LCT维护动态MST]
这题呢 就边权会在某一时刻变掉…众所周知LCT不支持删边的qwq…
所以考虑线段树分治… 直接码一发
如果 R+1 这个时间修改 那就当做 [L,R] 插入了一条边… 然后删的边和加的边存起来到栈 好删除贡献
注意一下最后一段加边…… 这题没了
#include <bits/stdc++.h>
#define rep(i , x , y) for(register int i = (x) , _## i = ((y) + 1) ; i < _## i ; i ++)
#define Rep(i , x , y) for(register int i = (x) , _## i = ((y) - 1) ; i > _## i ; i --)
using namespace std ;
#define int long long
using ll = long long ;
using pii = pair < int , int > ;
const static int _ = 1 << 20 ;
char fin[_] , * p1 = fin , * p2 = fin ;
inline char gc() { return (p1 == p2) && (p2 = (p1 = fin) + fread(fin , 1 , _ , stdin) , p1 == p2) ? EOF : * p1 ++ ; }
inline int read() {
bool sign = 1 ; char c = 0 ; while(c < 48) ((c = gc()) == 45) && (sign = 0) ;
int x = (c & 15) ; while((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15) ;
return sign ? x : -x ;
}
template < class T > void print(T x , char c = '\n') {
(x == 0) && (putchar(48)) , (x < 0) && (putchar(45) , x = -x) ;
static char _st[100] ; int _stp = 0 ;
while(x) _st[++ _stp] = x % 10 ^ 48 , x /= 10 ;
while(_stp) putchar(_st[_stp --]) ; putchar(c) ;
}
template < class T > void cmax(T & x , T y) { (x < y) && (x = y) ; }
template < class T > void cmin(T & x , T y) { (x > y) && (x = y) ; }
const int N = 5e4 + 10 ;
struct edge {
int u , v , w ;
}e[N << 2];
int n , m , q ;
vector < int > t[N << 2] ;
struct LCT {
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
int ch[N << 2][2] , fa[N << 2] , rev[N << 2] , mx[N << 2] , v[N << 2] ;
bool isroot(int x) { return ls(fa[x]) != x && rs(fa[x]) != x ; }
void pushdown(int x) {
if(rev[x]) {
if(ls(x)) rev[ls(x)] ^= 1 ;
if(rs(x)) rev[rs(x)] ^= 1 ;
rev[x] ^= 1 ; swap(ls(x) , rs(x)) ;
}
}
void pushup(int x) {
mx[x] = x ;
if(ls(x) && v[mx[ls(x)]] > v[mx[x]]) mx[x] = mx[ls(x)] ;
if(rs(x) && v[mx[rs(x)]] > v[mx[x]]) mx[x] = mx[rs(x)] ;
}
bool getr(int x) { return rs(fa[x]) == x ; }
void rotate(int x) {
int y = fa[x] , z = fa[y] , k = getr(x) , w = ch[x][k ^ 1] ;
if(! isroot(y)) ch[z][getr(y)] = x ;
fa[fa[fa[ch[ch[x][k ^ 1] = y][k] = w] = y] = x] = z ;
pushup(y) ; pushup(x) ;
}
void pushall(int x) {
if(! isroot(x)) pushall(fa[x]) ; pushdown(x) ;
}
void splay(int x) {
pushall(x) ;
while(! isroot(x)) {
int y = fa[x] ;
if(! isroot(y)) rotate(getr(x) ^ getr(y) ? x : y) ;
rotate(x) ;
}
}
void access(int x) {
for(int tp = 0 ; x ; x = fa[tp = x]) { splay(x) ; rs(x) = tp ; pushup(x) ; }
}
int findroot(int x) {
access(x) ; splay(x) ; while(ls(x)) x = ls(x) ; return x ;
}
void makeroot(int x) { access(x) ; splay(x) ; rev[x] ^= 1 ; }
void split(int x , int y) { makeroot(x) ; access(y) ; splay(y) ; }
void cut(int x, int y) { split(x , y) ;fa[x] = ls(y) = 0 ;pushup(y) ;}
void link(int x , int y) { makeroot(x) ; fa[x] = y ; }
int query(int x , int y) { return split(x , y) , mx[y] ; }
} T ;
void modify(int a , int b , int l , int r , int x , int rt) {
if(a > b) return ;
if(a <= l && r <= b) { t[rt].push_back(x) ;return ;}
int mid = l + r >> 1 ;
if(a <= mid) modify(a , b , l , mid , x , rt << 1) ;
if(b > mid) modify(a , b , mid + 1 , r , x , rt << 1 | 1) ;
}
int ss[N << 2] , st[N << 2] ;
int Ans = 0 , ans[N] , stop = 0 ;
void query(int l , int r , int rt) {
const int Stop = stop , mid = l + r >> 1 ;
for(auto p : t[rt]) {
int u = e[p].u ; int v = e[p].v ; int w = e[p].w ;
if(T.findroot(u) == T.findroot(v)) {
int mx = T.query(u , v) ;
if(T.v[mx] > w) {
T.cut(e[mx - n].u , mx) ; T.cut(e[mx - n].v , mx) ;
Ans -= e[mx - n].w ;
ss[++ stop] = mx - n ; st[stop] = 1 ;
}
else continue ;
}
T.link(p + n , u) ; T.link(p + n , v) ;
Ans += w ; ss[++ stop] = p ; st[stop] = -1 ;
}
if(l == r) ans[l] = Ans ;
else query(l , mid , rt << 1) , query(mid + 1 , r , rt << 1 | 1) ;
while(stop != Stop) {
if(st[stop] < 0) {
T.cut(ss[stop] + n , e[ss[stop]].u) ; T.cut(ss[stop] + n , e[ss[stop]].v) ;
Ans -= e[ss[stop]].w ;
}
else {
T.link(ss[stop] + n , e[ss[stop]].u) ; T.link(ss[stop] + n , e[ss[stop]].v) ;
Ans += e[ss[stop]].w ;
} stop -- ;
}
}
int L[N] , pos[N] , cnt ;
signed main() {
#ifdef _WIN64
freopen("testdata.in" , "r" , stdin) ;
#endif
n = read() ; m = read() ; q = read() ; cnt = m ;
rep(i , 1 , m) pos[i] = i , L[i] = 1 ;
rep(i , 1 , m) {
int u (read()) , v (read()) , w (read()) ; e[i] = { u , v , w } ;
}
rep(i , 1 , q) {
int k = read() , val = read() , x = pos[k] ;
modify(L[k] , i - 1 , 1 , q , x , 1) ;
L[k] = i ; e[++ cnt] = e[x] ; e[cnt].w = val ; pos[k] = cnt ;
}
rep(i , 1 , cnt) T.v[i + n] = e[i].w ;
rep(i , 1 , m) modify(L[i] , q , 1 , q , pos[i] , 1) ;
query(1 , q , 1) ; rep(i , 1 , q) print(ans[i]) ;
return 0 ;
}
P3206 [HNOI2010]城市建设 [线段树分治+LCT维护动态MST]的更多相关文章
- 【BZOJ2001】[HNOI2010]城市建设(CDQ分治,线段树分治)
[BZOJ2001][HNOI2010]城市建设(CDQ分治,线段树分治) 题面 BZOJ 洛谷 题解 好神仙啊这题.原来想做一直不会做(然而YCB神仙早就切了),今天来怒写一发. 很明显这个玩意换种 ...
- BZOJ2001 HNOI2010城市建设(线段树分治+LCT)
一个很显然的思路是把边按时间段拆开线段树分治一下,用lct维护MST.理论上复杂度是O((M+Q)logNlogQ),实际常数爆炸T成狗.正解写不动了. #include<iostream> ...
- bzoj 4025 二分图——线段树分治+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...
- 【洛谷P4319】 变化的道路 线段树分治+LCT
最近学了一下线段树分治,感觉还蛮好用... 如果正常动态维护最大生成树的话用 LCT 就行,但是这里还有时间这一维的限制. 所以,我们就把每条边放到以时间为轴的线段树的节点上,然后写一个可撤销 LCT ...
- 洛谷P3206 [HNOI2010]城市建设
神仙题 题目大意: 有一张\(n\)个点\(m\)条边的无向联通图,每次修改一条边的边权,问每次修改之后这张图的最小生成树权值和 话说是不是\(cdq\)题目都可以用什么数据结构莽过去啊-- 这道题目 ...
- P1975 [国家集训队]排队 线段树套平衡树维护动态逆序对查询
$ \color{#0066ff}{ 题目描述 }$ 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍 ...
- luogu P4172 [WC2006]水管局长 LCT维护动态MST + 离线
Code: #include<bits/stdc++.h> #define maxn 1200000 #define N 120000 using namespace std; char ...
- 【CDQ分治】[HNOI2010]城市建设
题目链接 线段树分治+LCT只有80 然后就有了CDQ分治的做法 把不可能在生成树里的扔到后面 把一定在生成树里的扔到并查集里存起来 分治到l=r,修改边权,跑个kruskal就行了 由于要支持撤销, ...
- 【LG3206】[HNOI2010]城市建设
[LG3206][HNOI2010]城市建设 题面 洛谷 题解 有一种又好想.码得又舒服的做法叫线段树分治+\(LCT\) 但是因为常数过大,无法跑过此题. 所以这里主要介绍另外一种玄学\(cdq\) ...
随机推荐
- Luogu P1330 封锁阳光大学 (黑白染色)
题意: 无向图,给一个顶点染色可以让他相邻的路不能通过,但是相邻顶点不能染色,求是否可以让所有的路不通,如果可以求最小染色数. 思路: 对于无向图中的每一个连通子图,都只有两种染色方法,或者染不了,直 ...
- 利用Kubernetes中的leaderelection实现组件高可用
在Kubernetes中,通常kube-schduler和kube-controller-manager都是多副本进行部署的来保证高可用,而真正在工作的实例其实只有一个.这里就利用到 leaderel ...
- C++中STL库函数的基本运用
学了这么长时间的STL库,现在我觉得是有必要对过去的题目和所遇到的问题做一下整理了,以便于之后更好的展开练习: 一. 为什么要用STL库? 1.简单粗暴(省事). 2.便于解决复杂的问题(在贪心题目中 ...
- thinkphp远程执行漏洞的本地复现
thinkphp远程执行漏洞的本地复现 0X00漏洞简介 由于ThinkPHP5 框架控制器名 没有进行足够的安全监测,导致在没有开启强制路由的情况下,可以伪装特定的请求可以直接Getshell(可以 ...
- WampServer 更换 mysql
下载另外版本的mysql,复制到 wamp/bin,初始化号 修改wamp 的/wampmanager.conf 复制相关配置文件 [mysqloptions] mysqlPortUsed = &qu ...
- MySql在Windows下自动备份的几种方法
以下几种全部是批处理命令中对于备份文件 1.复制date文件夹备份============================假想环境:MySQL 安装位置:C:\MySQL论坛数据库名称为:bbs数 ...
- java 自学简单框架(反射+注解)
1.先定义一个学生类 2.再定义一个teacher类(这个是为了练习多个注解,自己练习可以 不写这个) 3.再定义个一个学生老师类(这个是为了最终调用上面的那个学生类做准备) 4.下面开始真正的写框架 ...
- [Python]pip 国内源
临时使用方法 pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com celery END
- 干货!手把手教你使用数据可视化BI软件创建企业变更流程监控大屏
灯果数据可视化BI软件是新一代人工智能数据可视化大屏软件,内置丰富的大屏模板,可视化编辑操作,无需任何经验就可以创建属于你自己的大屏.大家可以在他们的官网下载软件. 本文以企业变更流程监控大屏为例 ...
- 流处理引擎(SPE)中的的分布式一致性语义之Exactly-Once和Effectively-Onece区别
-- At most Onece:最多一次,如果算子处理事件失败,事件将不再尝试该事件. -- At Least Onece:至少一次,如果算子处理事件失败,算子会再次尝试该处理事件,直到有一次成功. ...