3631: [JLOI2014]松鼠的新家
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1798 Solved: 875[][][]Description
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。
可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。维尼是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
Input
第一行一个整数n,表示房间个数
第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
Output
一共n行,第i行输出标号为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
2<= n <=300000
Source
//树刨模板题 #include#include #define lc k<<1#define rc k<<1|1using namespace std;const int N=3e5+5;struct edge{ int v,next;}e[N<<1];int tot,head[N];int n,m,dfs_cnt,fa[N],siz[N],son[N],dep[N],top[N],pos[N];int a[N],s[N],sum[N<<2],tag[N<<2];inline int read(){ int x=0;char ch=getchar(); while(ch<'0'||ch>'9'){ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0',ch=getchar();} return x;}inline void add(int x,int y){ e[++tot].v=y;e[tot].next=head[x];head[x]=tot; e[++tot].v=x;e[tot].next=head[y];head[y]=tot;}void dfs(int x,int f,int de){ dep[x]=de;fa[x]=f;siz[x]=1; for(int i=head[x];i;i=e[i].next){ if(e[i].v!=f){ dfs(e[i].v,x,de+1); siz[x]+=siz[e[i].v]; if(siz[son[x]] >1; tag[lc]+=tag[k]; tag[rc]+=tag[k]; sum[lc]+=tag[k]*(mid-l+1); sum[rc]+=tag[k]*(r-mid); tag[k]=0;}void change(int k,int l,int r,int x,int y,int val){ pushdown(k,l,r); if(l==x&&r==y){ tag[k]+=val; sum[k]+=val*(r-l+1); return ; } int mid=l+r>>1; if(y<=mid) change(lc,l,mid,x,y,val); else if(x>mid) change(rc,mid+1,r,x,y,val); else change(lc,l,mid,x,mid,val),change(rc,mid+1,r,mid+1,y,val); updata(k);}int query(int k,int l,int r,int x,int y){ pushdown(k,l,r); if(l==x&&r==y) return sum[k]; int mid=l+r>>1; if(y<=mid) return query(lc,l,mid,x,y); else if(x>mid) return query(rc,mid+1,r,x,y); else return query(lc,l,mid,x,mid)+query(rc,mid+1,r,mid+1,y); updata(k);}inline void vary(int x,int y){ change(1,1,n,pos[y],pos[y],-1); for(;top[x]!=top[y];x=fa[top[x]]){ if(dep[top[x]] dep[y]) swap(x,y); change(1,1,n,pos[x],pos[y],1);}void reset(int k,int l,int r){ if(l==r){ s[l]=sum[k];return ; } pushdown(k,l,r); int mid=l+r>>1; reset(lc,l,mid); reset(rc,mid+1,r);}int main(){ n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1,x,y;i