[JLOI2014]松鼠的新家

[JLOI2014]松鼠的新家

时间限制: 1 Sec  内存限制: 128 MB

题目描述

松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。
可是这样会导致**重复走很多房间,懒惰的**不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。**是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。

输入

第一行一个整数n,表示房间个数
第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

输出

一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让**有糖果吃。

样例输入

5
1 4 5 3 2
1 2
2 4
2 3
4 5

样例输出

1
2
1
2
1

 solution:

    非常裸地一个树链剖分

    

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 #define N 300005
  7 int read() {
  8     int s=0,f=1;
  9     char ch=getchar();
 10     while(ch>'9'||ch<'0') {
 11         if(ch=='-') {
 12             f=-1;
 13         }
 14         ch=getchar();
 15     }
 16     while(ch>='0'&&ch<='9') {
 17         s=(s<<1)+(s<<3)+(ch^48);
 18         ch=getchar();
 19     }
 20     return s*f;
 21 }
 22 int n,a[N],r[N],tot,deep[N],fa[N],size[N],son[N];
 23 int tree[N*4],lazy[N*4],top[N],first[N],cnt,pos[N];
 24 struct edge {
 25     int to,next;
 26 } c[N<<1];
 27 void add(int x,int y) {
 28     c[tot]=(edge) {
 29         y,r[x]
 30     };
 31     r[x]=tot++;
 32 }
 33 void dfs1(int x) {
 34     size[x]=1;
 35     son[x]=0;
 36     for(int i=r[x]; ~i; i=c[i].next) {
 37         if(fa[x]!=c[i].to) {
 38             fa[c[i].to]=x;
 39             deep[c[i].to]=deep[x]+1;
 40             dfs1(c[i].to);
 41             size[x]+=size[c[i].to];
 42             if(size[son[x]]<size[c[i].to]) {
 43                 son[x]=c[i].to;
 44             }
 45         }
 46     }
 47 }
 48 void dfs2(int u,int v) {
 49     top[u]=v;
 50     first[u]=++cnt;
 51     pos[cnt]=u;
 52     if(son[u]) {
 53         dfs2(son[u],v);
 54     }
 55     for(int i=r[u]; ~i; i=c[i].next) {
 56         if(c[i].to!=fa[u]&&c[i].to!=son[u]) {
 57             dfs2(c[i].to,c[i].to);
 58         }
 59     }
 60 }
 61 void pushup(int rt) {
 62     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
 63 }
 64 void pushdown(int rt,int len) {
 65     if(lazy[rt]) {
 66         lazy[rt<<1]+=lazy[rt];
 67         lazy[rt<<1|1]+=lazy[rt];
 68         tree[rt<<1]+=lazy[rt];
 69         tree[rt<<1|1]+=lazy[rt];
 70         lazy[rt]=0;
 71     }
 72 }
 73 void build(int i,int l,int r) {
 74     lazy[i]=0;
 75     if(l==r) {
 76         tree[i]=0;
 77         return ;
 78     }
 79     int mid=l+r>>1;
 80     build(i<<1,l,mid);
 81     build(i<<1|1,mid+1,r);
 82     pushup(i);
 83 }
 84 void change(int l,int r,int val,int i,int L,int R) {
 85     if(l<=L&&R<=r) {
 86         lazy[i]+=val;
 87         tree[i]+=val;
 88         return ;
 89     }
 90     pushdown(i,R-L+1);
 91     int mid=L+R>>1;
 92     if(l<=mid) {
 93         change(l,r,val,i<<1,L,mid);
 94     }
 95     if(r>mid) {
 96         change(l,r,val,i<<1|1,mid+1,R);
 97     }
 98     pushup(i);
 99 }
100 void Change(int x,int y,int val,int pd) {
101     int ji=x,kk=y;
102     int fx=top[x],fy=top[y];
103     while(fx!=fy) {
104         if(deep[fx]<deep[fy]) {
105             swap(x,y);
106             swap(fx,fy);
107         }
108         change(first[fx],first[x],val,1,1,n);
109         x=fa[fx];
110         fx=top[x];
111     }
112     if(deep[x]>deep[y]) {
113         swap(x,y);
114     }
115     change(first[x],first[y],val,1,1,n);
116     if(pd>1){ 
117         change(first[ji],first[ji],-val,1,1,n);
118     } 
119     if(pd==n-1){
120         change(first[kk],first[kk],-val,1,1,n);
121     }
122 }
123 int query(int pos,int i,int L,int R) {
124     if(L==R&&pos==L) {
125         return tree[i];
126     }
127     pushdown(i,R-L+1);
128     int mid=L+R>>1;
129     if(pos<=mid) {
130         return query(pos,i<<1,L,mid);
131     } else {
132         return query(pos,i<<1|1,mid+1,R);
133     }
134 }
135 int main() {
136     memset(r,-1,sizeof(r));
137     n=read();
138     for(int i=1; i<=n; ++i) {
139         a[i]=read();
140     }
141     for(int x,y,i=1; i<n; ++i) {
142         x=read(),y=read();
143         add(x,y);
144         add(y,x);
145     }
146     dfs1(1);
147     dfs2(1,-1);
148     build(1,1,n);
149     for(int i=1; i<n; ++i) {
150         Change(a[i],a[i+1],1,i);
151     }
152     for(int i=1; i<=n; ++i) {
153         int ans=query(first[i],1,1,n);
154         if(i<n){
155             printf("%d\n",ans);
156         }else{
157             printf("%d",ans);
158         }
159     }
160     return 0;
161 }

 

posted @ 2017-08-13 12:15  Forever_goodboy  阅读(143)  评论(0编辑  收藏  举报