可以發現更新操作就是\(\text\)的\(\text\)操作,這個操作複雜度是\(o(n\log n)\)的
因此,考慮對於每次的\(\text\)操作,維護每個點到根的路徑上不同的權值個數
每次\(\text\)操作只設計到合併兩個鏈/斷開一條鏈兩種操作,可以通過線段樹維護子樹修改
那麼修改的複雜度就是\(o(n\log^2 n)\)
對於二操作,自己模擬一下就知道,就是兩個點的答案-2\(\cdot \text\)答案+1
實現上有一些細節,就是更新的子樹根節點是需要查詢得到的
const int n=1e5+10;
int n,m;
vector g[n];
int l[n],r[n],dfn;
int son[n][2],fa[n],tfa[n][18],dep[n],id[n];
int s[n<<2],t[n<<2],mi[n];
void upd(int p,int l,int r,int ql,int qr,int x)
int mid=(l+r)>>1;
if(ql<=mid) upd(p<<1,l,mid,ql,qr,x);
if(qr>mid) upd(p<<1|1,mid+1,r,ql,qr,x);
s[p]=max(t[p<<1]+s[p<<1],t[p<<1|1]+s[p<<1|1]);
}int que(int p,int l,int r,int ql,int qr)
int que(int p,int l,int r,int x)
}void build(int p,int l,int r)
int mid=(l+r)>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
s[p]=max(s[p<<1],s[p<<1|1]);
}int dir(int x)
int isroot(int x)
void up(int p)
void rotate(int u)
void splay(int x)
void access(int x)
} // lct模板
void dfs(int u,int f)
int lca(int x,int y)
int main()
dfs(1,0),build(1,1,n);
rep(i,1,m) else
}}
Sdoi2017 樹點塗色 lct 線段樹
題意 一棵有根樹,支援x到根染成新顏色,求x到y顏色數,求x子樹裡點到根顏色數最大值 考場發現這個資訊是可減的,但是沒想到lct 特意設計成lct的形式!如何求顏色數?維護乙個點和父親的顏色是否一樣,不一樣為1,就是字首和。考慮相鄰的思想和那道 水位線 有點像 x到y的答案就是 s x s y 2 ...
SDOI2017 樹點塗色(LCT 線段樹)
給你一棵以 1 為根,有 n 個節點的樹,初始時每個節點的顏色互不相同,記一條路徑的權值為這條路徑 包括起點和終點 上所有不同的顏色個數,一共 m 個操作,每次支援以下 3 種操作之一 把點 x 到根節點的路徑上所有的點染上一種沒有用過的新顏色 求 x 到 y 的路徑的權值 在以 x 為根的子樹中選...
SDOI2017 樹點塗色
description bob有一棵n個點的有根樹,其中1號點是根節點。bob在每個點上塗了顏色,並且每個點上的顏色不同。定義一條路 徑的權值是 這條路徑上的點 包括起點和終點 共有多少種不同的顏色。bob可能會進行這幾種操作 1 x 把點x到根節點的路徑上所有的點染上一種沒有用過的新顏色。2 x ...