1. 程式人生 > >【刷題】BZOJ 4530 [Bjoi2014]大融合

【刷題】BZOJ 4530 [Bjoi2014]大融合

oot 記錄 聯通 tchar mar solution ever 數量 NPU

Description

小強要在N個孤立的星球上建立起一套通信系統。這套通信系統就是連接N個點的一個樹。

這個樹的邊是一條一條添加上去的。在某個時刻,一條邊的負載就是它所在的當前能夠

聯通的樹上路過它的簡單路徑的數量。

技術分享圖片

例如,在上圖中,現在一共有了5條邊。其中,(3,8)這條邊的負載是6,因

為有六條簡單路徑2-3-8,2-3-8-7,3-8,3-8-7,4-3-8,4-3-8-7路過了(3,8)。

現在,你的任務就是隨著邊的添加,動態的回答小強對於某些邊的負載的

詢問。

Input

第一行包含兩個整數N,Q,表示星球的數量和操作的數量。星球從1開始編號。

接下來的Q行,每行是如下兩種格式之一:

A x y 表示在x和y之間連一條邊。保證之前x和y是不聯通的。

Q x y 表示詢問(x,y)這條邊上的負載。保證x和y之間有一條邊。

1≤N,Q≤100000

Output

對每個查詢操作,輸出被查詢的邊的負載。

Sample Input

8 6
A 2 3
A 3 4
A 3 8
A 8 7
A 6 5
Q 3 8

Sample Output

6

Solution

LCT的特殊操作——維護子樹信息
開個額外的Isize,記錄節點虛子樹的信息和
然後就裸的題目了

#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
const int MAXN=100000+10; int n,q; #define lc(x) ch[(x)][0] #define rc(x) ch[(x)][1] struct LCT{ int ch[MAXN][2],fa[MAXN],rev[MAXN],size[MAXN],Isize[MAXN],stack[MAXN],cnt; 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) { size[x]=size[lc(x)]+size[rc(x)]+Isize[x]+1; } 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) { cnt=0; stack[++cnt]=x; for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i]; while(cnt)pushdown(stack[cnt--]); 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); Isize[x]+=size[rc(x)]; rc(x)=y; Isize[x]-=size[rc(x)]; pushup(x); } } inline void makeroot(int x) { access(x);splay(x);reverse(x); } inline void split(int x,int y) { makeroot(x);access(y);splay(y); } inline void link(int x,int y) { makeroot(x);access(y);splay(y); fa[x]=y; Isize[y]+=size[x]; pushup(y); } }; LCT T; #undef lc #undef rc 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 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);} 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(q); while(q--) { char opt[1];int x,y; scanf("%s",opt);read(x);read(y); if(opt[0]=='A')T.link(x,y); if(opt[0]=='Q') { T.split(x,y); write(1ll*(T.size[y]-T.size[x])*T.size[x],'\n'); } } return 0; }

【刷題】BZOJ 4530 [Bjoi2014]大融合