Time Limit: 10 Sec
Memory Limit: 128 MB
Description
松鼠的新家是一棵樹,前幾天剛剛裝修了新家,新家有個房間,並且有根樹枝連接,每個房間都可以相互到達,且倆個房間之間的路線都是唯一的。天哪,他居然真的住在“樹”上。松鼠想邀請小熊維尼前來參觀,並且還指定一份參觀指南,他希望維尼能夠按照他的指南順序,先去,再去,……,最後到,去參觀新家。
可是這樣會導致維尼重複走很多房間,懶惰的維尼不聽地推辭。可是松鼠告訴他,每走到一個房間,他就可以從房間拿一塊糖果吃。維尼是個饞傢伙,立馬就答應了。
現在松鼠希望知道爲了保證維尼有糖果吃,他需要在每一個房間各放至少多少個糖果。因爲松鼠參觀指南上的最後一個房間是餐廳,餐廳裏他準備了豐盛的大餐,所以當維尼在參觀的最後到達餐廳時就不需要再拿糖果吃了。
Input
第一行一個整數,表示房間個數
第二行個整數,依次描述
接下來行,每行兩個整數,表示標號和的兩個房間之間有樹枝相連。
Output
一共行,第行輸出標號爲i的房間至少需要放多少個糖果,才能讓維尼有糖果吃。
Sample Input
5
1 4 5 3 2
1 2
2 4
2 3
4 5
Sample Output
1
2
1
2
1
HINT
題解:
樹鏈剖分+線段樹區間修改,強行過了30萬…
每條路徑直接覆蓋,然後非起始點的點的答案需要,因爲會被加兩次。
upd:聽說有樹上差分這種操作…明天再學吧。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define INF 1999122700
using namespace std;
struct edge{
int to,nt;
}e[600004];
struct tree{
int tag,l,r,w;
}tr[1200004];
int n,ne,h[300004];
int cnt,a[300004];
int belong[300004],fa[300004],sz[300004],pos[300004],dep[300004];
void add(int u,int v){
e[++ne].to=v;e[ne].nt=h[u];
h[u]=ne;
}
void push(int k){
if(tr[k].tag==0)return ;
int g=tr[k].tag;tr[k].tag=0;
tr[k<<1].tag+=g;
tr[k<<1|1].tag+=g;
tr[k<<1].w+=g;
tr[k<<1|1].w+=g;
return ;
}
void build(int k,int l,int r){
tr[k].l=l;tr[k].r=r;
tr[k].tag=0;tr[k].w=0;
if(l==r)return ;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void inc(int k,int a,int b,int v){
int l=tr[k].l,r=tr[k].r;
if(l==a&&r==b){
tr[k].tag+=v;
tr[k].w+=v;
return ;
}
push(k);
int mid=(l+r)>>1;
if(b<=mid)inc(k<<1,a,b,v);
else if(a>mid)inc(k<<1|1,a,b,v);
else{
inc(k<<1,a,mid,v);
inc(k<<1|1,mid+1,b,v);
}
}
int ask(int k,int x){
int l=tr[k].l,r=tr[k].r;
if(l==x&&r==x)return tr[k].w;
push(k);
int mid=(l+r)>>1;
if(x<=mid)return ask(k<<1,x);
else return ask(k<<1|1,x);
}
void CLEAR(){
ne=0;cnt=0;sz[0]=0;
memset(h,0,sizeof(h));
}
void dfs1(int x){
sz[x]=1;
for(int i=h[x];i;i=e[i].nt){
if(e[i].to==fa[x])continue;
fa[e[i].to]=x;
dep[e[i].to]=dep[x]+1;
dfs1(e[i].to);
sz[x]+=sz[e[i].to];
}
return ;
}
void dfs2(int x,int chain){
int deg=0;
pos[x]=++cnt;
belong[x]=chain;
for(int i=h[x];i;i=e[i].nt){
if(e[i].to==fa[x])continue;
if(sz[deg]<sz[e[i].to]){
deg=e[i].to;
}
}
if(!deg)return ;
dfs2(deg,chain);
for(int i=h[x];i;i=e[i].nt){
if(e[i].to==fa[x])continue;
if(e[i].to!=deg)dfs2(e[i].to,e[i].to);
}
return ;
}
void solve(int x,int y){
while(belong[x]!=belong[y]){
if(dep[belong[x]]<dep[belong[y]])swap(x,y);
inc(1,pos[belong[x]],pos[x],1);
x=fa[belong[x]];
}
if(pos[x]>pos[y])swap(x,y);
inc(1,pos[x],pos[y],1);
return ;
}
int w33ha(){
CLEAR();
build(1,1,n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dep[0]=1;
dfs1(1);
dfs2(1,1);
for(int i=1;i<n;i++)solve(a[i],a[i+1]);
for(int i=1;i<=n;i++)printf("%d\n",ask(1,pos[i])-(a[1]!=i));
return 0;
}
int LiangJiaJun(){
while(scanf("%d",&n)!=EOF)w33ha();
return 0;
}