bzoj4817 動態樹 樹點塗色

2021-08-17 20:15:24 字數 2767 閱讀 2536

4817: [sdoi2017]樹點塗色

time limit: 10 sec memory limit: 128 mb

submit: 665 solved: 387

[submit][status][discuss]

description

bob有一棵n個點的有根樹,其中1號點是根節點。bob在每個點上塗了顏色,並且每個點上的顏色不同。定義一條路

徑的權值是:這條路徑上的點(包括起點和終點)共有多少種不同的顏色。bob可能會進行這幾種操作:

1 x:

把點x到根節點的路徑上所有的點染上一種沒有用過的新顏色。

2 x y:

求x到y的路徑的權值。

3 x y:

在以x為根的子樹中選擇乙個點,使得這個點到根節點的路徑權值最大,求最大權值。

bob一共會進行m次操作

input

第一行兩個數n,m。

接下來n-1行,每行兩個數a,b,表示a與b之間有一條邊。

接下來m行,表示操作,格式見題目描述

1<=n,m<=100000

output

每當出現2,3操作,輸出一行。

如果是2操作,輸出乙個數表示路徑的權值

如果是3操作,輸出乙個數表示權值的最大值

sample input

5 61 2

2 33 4

3 52 4 5

3 31 4

2 4 5

1 52 4 5

sample output

2 hint

source

鳴謝infinityedge上傳

[submit][status][discuss]

注意到如果把經過一條虛邊看作走了不同顏色。那麼操作1就是lct的access操作。所以用線段樹zici一下區間加和區間減就行了。注意到操作2的答案是f[x]+f[y]-2*f[lca]+1。這個畫圖證明即可。

(build線段樹裡面傳進去了val[l]而不是val[rev[l]]的wa了這麼久的應該就我乙個了吧

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

inline

int read()

const

int n=410000;

int lc[n],rc[n],fa[n];

int tot,fir[n],go[n],nex[n];

int acs[n],tag[n],size[n],dfn[n],tim,rev[n];

inline

void updata(int k)

inline

void tag_down(int k)

}inline

void query(int k,int l,int r,int l,int r,int &ans)

tag_down(k);

int mid=l+r>>1;

if(mid>=l) query(k<<1,l,mid,l,r,ans);

if(mid< r) query(k<<1|1,mid+1,r,l,r,ans);

updata(k);

}inline

void modify(int k,int l,int r,int l,int r,int v)

tag_down(k);

int mid=l+r>>1;

if(mid>=l) modify(k<<1,l,mid,l,r,v);

if(mid< r) modify(k<<1|1,mid+1,r,l,r,v);

updata(k);

}int n;

inline

void modify(int x,int v)

inline

void add(int x,int y)

inline

void rotate(int x)

if(lc[y]==x) lc[y]=b,rc[x]=y;

else rc[y]=b,lc[x]=y;

}inline

bool is_root(int x)

inline

void splay(int x)

rotate(x);

}}inline

void access(int q)

}int dep[n];

const

int maxlog=16;

int top[n][maxlog+1];

inline

int lca(int x,int y)

return top[x][0];

}inline

void dfs(int u,int f)

}int ans,tmp,lca;

inline

void build(int k,int l,int r)

int mid=l+r>>1;

build(k<<1,l,mid);

build(k<<1|1,mid+1,r);

updata(k);

}int m;

inline

int find_root(int x)

int main()

if(tp==3)

}}

Bzoj4817 SDOI2017 樹點塗色

bzoj 做個轉化 最開始都是虛邊 操作1 1 就是lc t role presentation lct lct裡的 acce ssa cc es s操作 求的就是路徑上虛邊的個數 1 然後就好辦了 用樹鏈剖分 線段樹來維護每個點到根虛邊的個數的最大值 操作1 1 access role prese...

BZOJ4817 Sdoi2017 樹點塗色

time limit 10 sec memory limit 128 mb submit 515 solved 302 submit status discuss bob有一棵n個點的有根樹,其中1號點是根節點。bob在每個點上塗了顏色,並且每個點上的顏色不同。定義一條路 徑的權值是 這條路徑上的點...

bzoj4817 SDOI2017 樹點塗色

bob有一棵n個點的有根樹,其中1號點是根節點。bob在每個點上塗了顏色,並且每個點上的顏色不同。定義一條路 徑的權值是 這條路徑上的點 包括起點和終點 共有多少種不同的顏色。bob可能會進行這幾種操作 1 x 把點x到根節點的路徑上所有的點染上一種沒有用過的新顏色。2 x y 求x到y的路徑的權值...