Gty的妹子樹

2022-07-13 20:48:38 字數 2189 閱讀 1118

我曾在弦歌之中聽過你,

檀板聲碎,半出折子戲。

舞榭歌台被風吹去,

歲月深處尚有餘音一縷……

gty神(xian)犇(chong)從來不缺妹子……

他來到了一棵妹子樹下,發現每個妹子有乙個美麗度……

由於gty很哲♂學,他只對美麗度大於某個值的妹子感興趣。

他想知道某個子樹中美麗度大於k的妹子個數。

某個妹子的美麗度可能發生變化……

樹上可能會出現乙隻新的妹子……

維護一棵初始有n個節點的有根樹(根節點為1),樹上節點編號為1-n,每個點有乙個權值wi。

支援以下操作:

0 u x 詢問以u為根的子樹中,嚴格大於x的值的個數。(u^=lastans,x^=lastans)

1 u x 把u節點的權值改成x。(u^=lastans,x^=lastans)

2 u x 新增乙個編號為"當前樹中節點數+1"的節點,其父節點為u,其權值為x。(u^=lastans,x^=lastans)

最開始時lastans=0。

input

輸入第一行包括乙個正整數n(1<=n<=30000),代表樹上的初始節點數。

接下來n-1行,每行2個整數u,v,為樹上的一條無向邊。

任何時刻,樹上的任何權值大於等於0,且兩兩不同。

接下來1行,包括n個整數wi,表示初始時每個節點的權值。

接下來1行,包括1個整數m(1<=m<=30000),表示操作總數。

接下來m行,每行包括三個整數 op,u,v:

op,u,v的含義見題目描述。

保證題目涉及的所有數在int內。

output

對每個op=0,輸出一行,包括乙個整數,意義見題目描述。

sample input

21 2

10 20

10 1 5

sample output

sol:

首先dfs,對於每個節點,如果這個節點的父親節點所在塊未滿,就塞進父節點所在塊中,否則自成一塊,每一塊記錄塊的根節點,然後與父節點所在的塊的根節點連邊 。

我們記錄每個節點所屬的塊,即塊的根節點,建立兩個圖:乙個圖存原樹(雙向邊),乙個圖存塊的連通性(單向邊)。

我們維護塊內的元素有序,可以用鍊錶。

如果乙個節點是第乙個加入塊的,那麼不會有別的子樹的節點屬於這個塊,那麼我們在查詢乙個子樹時,只需要從子樹的根開始向下遍歷,先處理這些不在完整塊內的點,一旦我們碰到了別的塊內的點,就立即轉移到塊的圖上去跑。

例如查詢5,6:5不是塊的根節點,所以查詢單個節點5,再查詢單個節點7,再查詢節點6,發現6是塊的根節點,可以在用二分法在塊有序鍊錶找到》6的節點個數,再查詢節點10,發現10也是塊的根節點

inline int read()//快速讀入

while (ch>='0'&&ch<='9')

return x*f;

}struct node

}map,block,link;

void dfs(int u,int f)//一遍dfs,分塊

}void init()

for(i=1;i<=n;i++)

w[i]=read(), top[i]=i, size[i]=1;

dfs(1,0);

for(i=1;i<=n;i++)

if(top[i]==i)

sort(list[i].begin(),list[i].end());//同一塊內的節點權值鏈從小到大排序

}void work()

else

if(opt==1) // 把u節點的權值改成x

else

else//塊中節點個數滿了 }}

}int main()

樹上分塊 Gty的妹子樹

我們需要查詢樹上問題資訊,考慮樹上分塊。我們可以把樹分成大小為n sqrt n n 的若干個連通塊。每乙個塊內用結構體記錄,支援修改操作,插入操作和查詢操作。現在我們考慮如何實現下面三個操作 照樣每一次操作的時間複雜度是o n o sqrt n o n 的。對於詢問x子樹的答案,我們可以根據分塊特性...

bzoj3720 Gty的妹子樹

我們可以樹上分塊,詳見我部落格中雜文下的根號演算法題庫 然後每個塊維護降序,對於整一塊在子樹內的就可以二分,其餘部分暴力。include include include include define fo i,a,b for i a i b i using namespace std const i...

BZOJ3720 Gty的妹子樹

如果沒有插入操作,那麼直接對dfs序建立線段樹套平衡樹即可,有插入操作的話,將外層的線段樹換成重量平衡樹即可。一開始寫替罪羊樹套權值線段樹無限mle 所以只好寫替罪羊樹套treap include include includeusing namespace std typedef unsigned...