1. 程式人生 > >【刷題】BZOJ 2816 [ZJOI2012]網絡

【刷題】BZOJ 2816 [ZJOI2012]網絡

size stack swap pty ota rip ++ gpo -m

Description

http://www.lydsy.com/JudgeOnline/upload/zjoi2012.pdf

Solution

維護樹上聯通塊的信息,支持動態加邊刪邊
LCT
總共只有10種顏色,直接建10個LCT,每個LCT維護一種顏色
LCT還是差不多
只是第二個操作比較麻煩,得一個一個顏色地去試

#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
#define lc(x) ch[(x)][0]
#define rc(x) ch[(x)][1]
const int
MAXN=10000+10,MAXC=15; int n,m,c,k,Val[MAXN],d[MAXC][MAXN]; template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);} template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);} struct LCT{ int ch[MAXN][2],fa[MAXN],rev[MAXN],Mx[MAXN]; inline void init() { memset(ch,0
,sizeof(ch)); memset(fa,0,sizeof(fa)); memset(rev,0,sizeof(rev)); memset(Mx,0,sizeof(Mx)); } inline bool nroot(int x) { return lc(fa[x])==x||rc(fa[x])==x; } inline void reverse(int x) { std::swap(lc(x),rc(x)); rev[x]^=1; } inline
void pushup(int x) { Mx[x]=Val[x]; chkmax(Mx[x],Mx[lc(x)]); chkmax(Mx[x],Mx[rc(x)]); } inline void pushdown(int x) { if(rev[x]) { if(lc(x))reverse(lc(x)); if(rc(x))reverse(rc(x)); rev[x]=0; } } inline void rotate(int x) { int f=fa[x],p=fa[f],c=(rc(f)==x); if(nroot(f))ch[p][rc(p)==f]=x; fa[ch[f][c]=ch[x][c^1]]=f; fa[ch[x][c^1]=f]=x; fa[x]=p; pushup(f); pushup(x); } inline void splay(int x) { std::stack<int> s; s.push(x); for(register int i=x;nroot(i);i=fa[i])s.push(fa[i]); while(!s.empty())pushdown(s.top()),s.pop(); for(register int y=fa[x];nroot(x);rotate(x),y=fa[x]) if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x); pushup(x); } inline void access(int x) { for(register int y=0;x;x=fa[y=x])splay(x),rc(x)=y,pushup(x); } inline void makeroot(int x) { access(x);splay(x);reverse(x); } inline int findroot(int x) { access(x);splay(x); while(lc(x))pushdown(x),x=lc(x); splay(x); return x; } inline void split(int x,int y) { makeroot(x);access(y);splay(y); } inline void link(int x,int y) { makeroot(x); if(findroot(y)!=x)fa[x]=y; } inline void cut(int x,int y) { makeroot(x); if(findroot(y)==x&&fa[y]==x&&!lc(y))rc(x)=fa[y]=0,pushup(x); } }; LCT T[MAXC]; template<typename T> inline void read(T &x) { T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w; } template<typename T> inline void write(T x,char c='\0') { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(c!='\0')putchar(c); } template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} int main() { read(n);read(m);read(c);read(k); for(register int i=1;i<=c;++i)T[i].init(); for(register int i=1;i<=n;++i)read(Val[i]); for(register int i=1;i<=m;++i) { int u,v,w; read(u);read(v);read(w); w++; d[w][u]++;d[w][v]++; T[w].link(u,v); } while(k--) { int opt; read(opt); if(opt==0) { int x,y; read(x);read(y); Val[x]=y; for(register int i=1;i<=c;++i)T[i].access(x),T[i].splay(x),T[i].pushup(x); } if(opt==1) { int u,v,w,dn=1; read(u);read(v);read(w); w++; for(register int i=1;i<=c;++i) if(T[i].findroot(u)==T[i].findroot(v)) { T[i].makeroot(u),T[i].access(v),T[i].splay(v); if(T[i].lc(v)!=u||T[i].rc(u))continue; dn=0; if(i==w)puts("Success."); else if(d[w][u]>=2||d[w][v]>=2)puts("Error 1."); else if(T[w].findroot(u)==T[w].findroot(v))puts("Error 2."); else { T[i].cut(u,v);T[w].link(u,v); d[i][u]--;d[i][v]--; d[w][u]++;d[w][v]++; puts("Success."); } break; } if(dn)puts("No such edge."); } if(opt==2) { int c,u,v; read(c);read(u);read(v); c++; if(T[c].findroot(u)!=T[c].findroot(v))puts("-1"); else T[c].split(u,v),write(T[c].Mx[v],'\n'); } } return 0; }

【刷題】BZOJ 2816 [ZJOI2012]網絡