SDOI2017 樹點塗色 LCT 線段樹

2022-05-20 05:05:02 字數 1261 閱讀 3887

可以發現更新操作就是\(\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 ...