ZJOI2016 大森林 題解

2022-09-23 01:36:13 字數 2600 閱讀 7788

lct

對 lct 有了更深的理解

參考 flashhu

有 \(n\) 棵樹,初始各有 \(1\) 個編號為 \(1\) 的節點,稱它們為生長節點。

\(m\) 個操作,\(3\) 種之一:

\(n\le 10^5,m\le 2\times 10^5\)

顯然我們有 \(o(n^2 \log n)\) 的暴力 lct 做法,但是好像空間有點著不住

最初的想法是說容易發現其實很多邊都是一樣的,所以我們可以嘗試資料結構優化建圖之類的

經過思考之後發現不會,其問題在於 \(1\) 操作過後的區間關係沒有特殊關係(相離/包含)

於是我們有了這樣的基礎思想:從 \(1\) 到 \(n\) 列舉每棵樹,每次只考慮相鄰兩棵樹之間的差異,只需要在前一棵樹的基礎上快速地得到這棵樹的形態就可以了

考慮乙個操作 \(1\ l\ r\ x\) 的影響,先假裝所有樹都是一樣的

發現其造成的差異只有 \(l-1\) 和 \(l\) ,\(r\) 和 \(r+1\) 這兩個位置,知道

第 \(l\) 棵樹是第 \(l-1\) 棵樹把這個 \(1\) 操作以後 原來生長節點上的所有子樹全部轉而接到 \(x\) 上。

第 \(r+1\) 棵樹是第 \(r\) 棵樹把這些子樹接回來

圖醜爆了(

現在的問題在於如何把這些子樹快速地扔過去,考慮給他乙個虛點

也就是說,我們每次在進行 \(1\) 操作的時候,我們給他新建乙個虛點 \(img\) ,

最開始 \(link(img,grow)\) ,然後讓 \(grow^=img\) ,之後就直接掛在 \(img\) 上

然後到 \(l-1\) 和 \(l\) 的時候,我們讓 \(img\) 改成連 \(x\)

把每個操作拆成兩個端點,以端點為第一關鍵字,原時間順序為第二關鍵字排序,再從左到右乙個個處理即可

現在考慮處理過程中的詢問

容易想到設實點權 \(1\) ,虛點權 \(0\) ,然後只需要 \(makeroot(u),access(v),splay(v)\) 三連即可?

發現好像不是很行,因為固定根 \(1\) 我們 \(makeroot(u)\) 可能會改掉一些父子關係

同時,考慮到兩個實點的路徑上有可能存在虛點,而虛點可能包含了非路徑上的資訊,我們考慮樹上差分

假裝都會 lct 求 lca,那麼答案就是 \(siz[u]+siz[y]-2\times siz[lca]\) ,注意這些 \(siz[tmp]\) 一定都要 \(access(tmp)\) 之後取用

時間複雜度 \(o(n\log n)\)

#include#define ls(rt) t[rt].ch[0]

#define rs(rt) t[rt].ch[1]

#define swap(x,y) x^=y^=x^=y

#define min(x,y) ((x)

#define max(x,y) ((x)>(y)?(x):(y))

using namespace std;

const int n = 2e5+5;

char buf[1<<23],*p1=buf,*p2=buf;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?eof:*p1++)

int read()

while(isdigit(ch))s=s*10+(ch^48),ch=getchar();

return s*w;

}struct treet[n];

struct itemitem[n];

int gl[n],gr[n],pos[n],ans[n];

int n,m,grow,cnt,img,tim,tot;

void pushup(int rt)

bool check(int rt)

bool identity(int rt)

void rotate(int rt)

void splay(int rt)

}int access(int rt,int p=0)

void cut(int rt)

inline void link(int p,int q)

/*本題中的 link 比較特殊,既不需要 makeroot ,也不用 splay

考慮 link 使用場景,無非是新建的點(虛點)或者離線求解時的轉移

新建點的點顯然就是根了,而另外一種,因為我們已經 cut 了,所以也是根

所以直接把父親設為 q 即可

*/signed main(),//保證修改在詢問前

item[++tot]=(item);

grow=img;

}if(op==2)

x=read(),item[++tot]=(item);

}// 此時,lct 維護出了如果沒有任何 1 操作時的樹並準備好了所有虛點

sort(item+1,item+1+tot,(item a,item b)

ZJOI2016 解題報告

我大浙的省選題真是超級神仙 這套已經算是比較可做的了。神仙分治題。對於乙個矩形,每次我們從最長邊切開,最短邊不會超過 sqrt 所以對於每個點跑一遍最短路就行了。時間複雜度 o n sqrt log n q sqrt code below include define id i,j i 1 m j ...

ZJOI2016 線段樹 解題報告

很久以前看過題面然後沒有仔細想,再做的時候忘了序列是隨機的了。然後怎麼搞都是o n4 的。我們可以將狀態設為f x,i,l,r 表示在i次操作後,l,r x,l 1和r 1大於等於x的方案數。不妨認為a 0 a n 1 這樣的話假如說有跨越區間端點的操作,那麼就一定會使操作中的數 x。然後令g x,...

ZJOI2016一試 醬油記

day1 上午rzz stilwell?講數學,就推 cai 出了第一道。然後聽懂了一點點就開始碎覺了。聽到雜題的時候就又復活辣 下午感覺畫風明顯不對啊。怎麼變成dp了。然後還有樹分治。day2 上午居然講底層運算。講到實數就開始碎覺了。不過感覺o2很茲瓷哦 然後還有分塊,不過裡面的數國隊都講過辣,...