bzoj2594 [Wc2006]水管局長資料加強版(lct+kruskal+離線)
考慮離線操作,倒著做,就是維護不斷往裡加邊的最小生成樹。具體做法與魔法森林差不多。
至於如何找到一條邊的標號,可以二分查詢來做。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define N 2100010
#define ll long long
#define inf 0x3f3f3f3f
inline char gc(){
static char buf[1<<16],*S,*T;
if (S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,Q,fa[N],c[N][2],v[N],mx[N],qq[N],tot=0 ,pa[100010],ans[100010];
bool rev[N],bad[N>>1];
struct quer{
int op,x,y,id;
}q[100010];
struct edge{
int x,y,val,id;
edge(){};
edge(int _x,int _y){x=_x;y=_y;}
friend bool operator<(edge a,edge b){return a.x==b.x?a.y<b.y:a.x<b.x;}
}e[N>>1];
inline bool cmp(edge a,edge b){return a.val<b.val;}
inline bool cmp2(edge a,edge b){return a.id<b.id;}
inline int find(int x){return x==pa[x]?x:pa[x]=find(pa[x]);}
inline bool isroot(int x){return x!=c[fa[x]][0]&&x!=c[fa[x]][1];}
inline void update(int x){
int l=c[x][0],r=c[x][1];
if(v[mx[l]]>=v[mx[r]]&&v[mx[l]]>=v[x]) mx[x]=mx[l];
else if(v[mx[r]]>v[x]) mx[x]=mx[r];else mx[x]=x;
}
inline void pushdown(int p){
if(!rev[p]) return;rev[p]=0;swap(c[p][0],c[p][1]);
rev[c[p][0]]^=1;rev[c[p][1]]^=1;
}
inline void rotate(int x){
int y=fa[x],z=fa[y],l=x==c[y][1],r=l^1;
if(!isroot(y)) c[z][y==c[z][1]]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;update(y);update(x);
}
inline void splay(int x){
int top=0;qq[++top]=x;
for(int xx=x;!isroot(xx);xx=fa[xx]) qq[++top]=fa[xx];
while(top) pushdown(qq[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(x==c[y][1]^y==c[z][1]) rotate(x);
else rotate(y);
}rotate(x);
}
}
inline void access(int x){
int y=0;while(x){splay(x);c[x][1]=y;update(x);y=x;x=fa[x];}
}
inline void makeroot(int x){
access(x);splay(x);rev[x]^=1;
}
inline void link(int x,int y){
makeroot(x);fa[x]=y;
}
inline void cut(int x,int y){
makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0,update(y);
}
inline int qmax(int x,int y){
makeroot(x);access(y);splay(y);return mx[y];
}
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();Q=read();
for(int i=1;i<=m;++i){
e[i].x=read(),e[i].y=read(),e[i].val=read();v[i+n]=e[i].val;mx[i+n]=i+n;
if(e[i].x>e[i].y) swap(e[i].x,e[i].y);e[i].id=i;
}sort(e+1,e+m+1);
for(int i=1;i<=Q;++i){
q[i].op=read();q[i].x=read();q[i].y=read();
if(q[i].op==1){q[i].id=++tot;continue;}
if(q[i].x>q[i].y) swap(q[i].x,q[i].y);
q[i].id=lower_bound(e+1,e+m+1,edge(q[i].x,q[i].y))->id;bad[q[i].id]=1;
}sort(e+1,e+m+1,cmp);
for(int i=1;i<=n;++i) pa[i]=i;int ofo=0;
for(int i=1;i<=m;++i){
if(ofo==n-1) break;
if(bad[e[i].id]) continue;
int x=e[i].x,y=e[i].y,xx=find(x),yy=find(y);
if(xx==yy) continue;ofo++;pa[xx]=yy;link(x,e[i].id+n);link(e[i].id+n,y);
}sort(e+1,e+m+1,cmp2);
for(int i=Q;i;--i){
if(q[i].op==1){ans[q[i].id]=e[qmax(q[i].x,q[i].y)-n].val;continue;}
int x=q[i].x,y=q[i].y,t=q[i].id,old=qmax(x,y);
if(v[t+n]>=v[old]) continue;cut(e[old-n].x,old);cut(e[old-n].y,old);
link(x,t+n);link(t+n,y);
}for(int i=1;i<=tot;++i) printf("%d\n",ans[i]);
return 0;
}
相關推薦
bzoj2594 [Wc2006]水管局長資料加強版(lct+kruskal+離線)
考慮離線操作,倒著做,就是維護不斷往裡加邊的最小生成樹。具體做法與魔法森林差不多。 至於如何找到一條邊的標號,可以二分查詢來做。 #include <cstdio> #include <cstring> #include <al
[BZOJ2594][Wc2006]水管局長資料加強版(kruskal+lct)
題目描述 傳送門 題解 寫lct就應該有那種誓死不看板子的氣魄。 這道題思路還是很清晰的,維護一棵最小生成樹,每一次找樹鏈上權值最大的邊 刪邊變成倒序加邊 最開始的時候用沒有刪的邊kruskal直接最小生成樹 動態的話就是維護一棵lct,每一次加邊
BZOJ2594 [Wc2006]水管局長資料加強版【LCT】
Description SC省MY市有著龐大的地下水管網路,嘟嘟是MY市的水管局長(就是管水管的啦),嘟嘟作為水管局長的工作就是:每天供水公司可能要將一定量的水從x處送往y處,嘟嘟需要為供水公司找到一條從A至B的水管的路徑,接著通過資訊化的控制中心通知路徑上的
bzoj2594: [Wc2006]水管局長資料加強版
題目大意:給定一個簡單圖,支援刪邊,每次詢問兩點間 最大邊權值最小的路徑。 思路:題目中權值在邊上,而LCT維護的全值在點上,所以要先轉化,對於連線x和y的第i條路徑,把邊變成第i+n個點,然後把權值放到邊點上,所有真正的點權值賦為0,這也是維護邊權的常用方法。接著就是一
【bzoj2594】[Wc2006]水管局長資料加強版 link cut tree
好久的坑了,今天終於填上了。 一直想總結一下LCT,結果發現難題都不會做。 離線處理,因為刪邊比較難做,所以我們倒著做變成加邊操作。 問題轉化成加邊維護最小生成樹,用lct維護一下最大的邊是哪一條,一旦新加入的邊形成環了,那麼看一看環上最大的邊和新加入的邊哪個大,如果新加入
BZOJ 2594: [Wc2006]水管局長資料加強版(lct)
傳送門 解題思路 一道\(lct\)維護動態最小生成樹。剛開始寫了一遍瘋狂\(Re\),冷靜了一下重新寫了一遍終於過了。首先題目中要求兩點之間最大值的最小值,其實就是維護一個最小生成樹,每次詢問最大值。要將刪邊轉化成加邊操作,就是倒著處理,這裡用\(set\)和\(map\)就比較方便。然後還要把邊權
[動態樹 LCT] BZOJ 2594 [Wc2006]水管局長資料加強版
動態樹模板題 最開始加邊用Kruskal比較快,不用LCT,然後再用LCT維護最小生成樹 話說這道題小資料範圍的正解是什麼.... PS:以前LCT的求根都是打錯的,沒有pushdown() #include<cstdio> #include<cstd
BZOJ 2594: [Wc2006]水管局長資料加強版(LCT+最小生成樹+離線)
題目戳我 Solution 題目大意:就是讓你維護一棵動態的最小生成樹, 並詢問兩點路徑中邊權最大值。 很明顯,用LCT來做這個。有幾個關鍵點: ①刪邊維護mst不好搞,我們離線然後刪邊變加邊。 ②一開始用kruskal搞出底圖的mst,然後加
BZOJ 2594 [Wc2006]水管局長資料加強版
由於題目有刪除操作,所以我們不妨倒敘列舉,把刪邊變成加邊。某人還起了個好聽的名字叫“時光倒流”…… 之後用動態樹維護一下動態最小生成樹就行了,每加入一條邊就用動態樹樹找出兩點見最長邊,比較大小看是否能替換就行了。 這裡還有一個小技巧,就是二分邊標號來找出每個
BZOJ 2594 [Wc2006]水管局長資料加強版 LCT
題意:連結 方法: LCT 解析: 搞了一個上午加1個小時的題,TM最後大錯誤居然是排序元素太多排不回原來的樣子! 我要重新學排序! 這題是用LCT維護動態最小生成樹,但是最小生成樹上刪邊應該是做不到的,所以我們可以離線操作,之後先把所
【BZOJ2594】【WC2006】水管局長資料加強版
【題目連結】【思路要點】若題目僅包含詢問操作,顯然我們只需保留一棵圖的最小生成樹,在樹上詢問兩點間邊權的最大值即可。而本題中多了一種刪邊操作,但沒有強制線上,因此,我們可以將操作離線,轉化為加邊操作。用LinkCutTree維護動態最小生成樹即可。時間複雜度\(O((M+Q)
[BZOJ2594][Wc2006][LCT]水管局長資料加強版
題意 給一張圖,每次操作或詢問所有u到v路徑上邊權最大值的最小值,或刪除一條邊 離線,反過來操作,刪邊變成加邊,用LCT維護圖的聯通就行。 #include <cstdio> #include <iostream> #inc
BZOJ 3514: Codechef MARCH14 GERALD07加強版(LCT + 主席樹)
typename pda 在線的 發現 () rev rdo getc nod 題意 \(N\) 個點 \(M\) 條邊的無向圖,詢問保留圖中編號在 \([l,r]\) 的邊的時候圖中的聯通塊個數。 \(K\) 次詢問強制在線。 \(1\le N,M,K \le 200,0
bzoj2594: [Wc2006]水管局長數據加強版
date get push roo 表示 sort 選擇 mit 管道 地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2594 題目: 2594: [Wc2006]水管局長數據加強版 Time Limit:
BZOJ2594 [Wc2006]水管局長數據加強版【LCT】
最短 一次 read amp std 之前 應輸入 NPU 進入 Description SC省MY市有著龐大的地下水管網絡,嘟嘟是MY市的水管局長(就是管水管的啦),嘟嘟作為水管局長的工作就是:每天供水公司可能要將一定量的水從x處送往y處,嘟嘟需要為供水公司找到一條從A至
BZOJ 3674 可持久化並查集加強版(主席樹變形)
als ret desc scan sync scanf ops 只需要 ica 3673: 可持久化並查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [
bzoj5037 線段樹練習4加強版(暴力分塊)
log del string 技術分享 iostream || getc code click 求大爺教線段樹怎麽寫啊QAQ 只會寫分塊...一開始腦抽寫成了O(NKlogN)還被CZL大爺嘲諷了一發T T f[i][j]表示在第i塊中,模k為j的數有幾個,
NYOJ 290 動物統計加強版(字典樹題)
動物統計加強版 時間限制:3000 ms | 記憶體限制:150000 KB 難度:4 輸入 第一行輸入動物名字的數量N(1<= N <= 4000000),接下來的N行輸入N個字串表示動物的名字(字串的長度不超過10,字串全為小寫字母,並且只有一
三維一邊推:最長公共子序列加強版(三串LCS) CAIOJ - 1073 dp lcs
題解 與二位lcs類似 列舉三個串的每個位置 狀態轉移考慮5種情況 abc當前位置全相等則由3個串長度全-1的位置轉移過來 lcs+1 ab相等但不與c相等 則由ab長度都-1或c長度-1取max轉移過來 ac相等但不與b相等和bc相等但不與a相等類似 abc互不相等則由a、b或c長度-
NYOJ 290 動物統計加強版(字典樹姍姍來遲)
// trietree.cpp : 定義控制檯應用程式的入口點。//#include<cstdio>#include<iostream>#include<string.h>using namespace std;const int num_chars = 26;