1. 程式人生 > >BZOJ2049:[SDOI2008]洞穴勘測——題解

BZOJ2049:[SDOI2008]洞穴勘測——題解

ios destroy you 實時 模板題 hellip != access 寫法

http://www.lydsy.com/JudgeOnline/problem.php?id=2049

https://www.luogu.org/problemnew/show/P2147

輝輝熱衷於洞穴勘測。

某天,他按照地圖來到了一片被標記為JSZX的洞穴群地區。經過初步勘測,輝輝發現這片區域由n個洞穴(分別編號為1到n)以及若幹通道組成,並且每條通道連接了恰好兩個洞穴。假如兩個洞穴可以通過一條或者多條通道按一定順序連接起來,那麽這兩個洞穴就是連通的,按順序連接在一起的這些通道則被稱之為這兩個洞穴之間的一條路徑。 洞穴都十分堅固無法破壞,然而通道不太穩定,時常因為外界影響而發生改變,比如,根據有關儀器的監測結果,123號洞穴和127號洞穴之間有時會出現一條通道,有時這條通道又會因為某種稀奇古怪的原因被毀。

輝輝有一臺監測儀器可以實時將通道的每一次改變狀況在輝輝手邊的終端機上顯示:

如果監測到洞穴u和洞穴v之間出現了一條通道,終端機上會顯示一條指令 Connect u v

如果監測到洞穴u和洞穴v之間的通道被毀,終端機上會顯示一條指令 Destroy u v

經過長期的艱苦卓絕的手工推算,輝輝發現一個奇怪的現象:無論通道怎麽改變,任意時刻任意兩個洞穴之間至多只有一條路徑。

因而,輝輝堅信這是由於某種本質規律的支配導致的。因而,輝輝更加夜以繼日地堅守在終端機之前,試圖通過通道的改變情況來研究這條本質規律。 然而,終於有一天,輝輝在堆積成山的演算紙中崩潰了……他把終端機往地面一砸(終端機也足夠堅固無法破壞),轉而求助於你,說道:“你老兄把這程序寫寫吧”。

輝輝希望能隨時通過終端機發出指令 Query u v,向監測儀詢問此時洞穴u和洞穴v是否連通。現在你要為他編寫程序回答每一次詢問。 已知在第一條指令顯示之前,JSZX洞穴群中沒有任何通道存在。

LCT模板題,你可以很輕松的百度出一個LCT寫法教程,這裏就不多言了。

提供一個模板代碼。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include
<queue> #include<cmath> using namespace std; const int N=1e4+5; int n,m,r,fa[N],tr[N][2],rev[N],q[N]; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch==-;ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } inline bool get(int x){ return tr[fa[x]][1]==x; } inline bool isroot(int x){ if(!fa[x])return 1; return tr[fa[x]][0]!=x&&tr[fa[x]][1]!=x; } inline void pushrev(int x){ if(!rev[x])return; swap(tr[x][0],tr[x][1]); if(tr[x][0])rev[tr[x][0]]^=1; if(tr[x][1])rev[tr[x][1]]^=1; rev[x]=0; } inline void rotate(int x){ int y=fa[x],z=fa[y],b=tr[y][0]==x?tr[x][1]:tr[x][0]; if(z&&!isroot(y))(tr[z][0]==y?tr[z][0]:tr[z][1])=x; fa[x]=z;fa[y]=x;b?fa[b]=y:0; if(tr[y][0]==x)tr[x][1]=y,tr[y][0]=b; else tr[x][0]=y,tr[y][1]=b; } inline void splay(int x){ q[r=0]=x; for(int y=x;!isroot(y);y=fa[y])q[++r]=fa[y]; for(int i=r;i>=0;i--)pushrev(q[i]); while(!isroot(x)){ if(!isroot(fa[x])) rotate((get(x)==get(fa[x])?fa[x]:x)); rotate(x); } } inline void access(int x){ for(int y=0;x;y=x,x=fa[x]){ splay(x);tr[x][1]=y; if(y)fa[y]=x; } } inline int findroot(int x){ access(x);splay(x); while(pushrev(x),tr[x][0])x=tr[x][0]; splay(x); return 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); tr[y][0]=0;fa[x]=0; } int main(){ n=read(),m=read(); for(int i=1;i<=m;i++){ char ch=getchar(); while(ch<A||ch>Z)ch=getchar(); if(ch==Q){ if(findroot(read())==findroot(read()))puts("Yes"); else puts("No"); }else if(ch==C)link(read(),read()); else cut(read(),read()); } return 0; }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ2049:[SDOI2008]洞穴勘測——題解