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很茲瓷哦 然後還有分塊,不過裡面的數國隊都講過辣,...