BZOJ3631 [JLOI2014]松鼠的新家

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

 

正解:树链剖分+线段树

解题报告:

  链剖裸题。

 

  1 //It is made by jump~
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <ctime>
  9 #include <vector>
 10 #include <queue>
 11 #include <map>
 12 #include <set>
 13 #ifdef WIN32   
 14 #define OT "%I64d"
 15 #else
 16 #define OT "%lld"
 17 #endif
 18 using namespace std;
 19 typedef long long LL;
 20 const int MAXN = 300011;
 21 const int MAXM = 600011;
 22 int n,ecnt;
 23 int first[MAXN],next[MAXM],to[MAXM];
 24 int top[MAXN],son[MAXN],deep[MAXN],father[MAXN],id[MAXN],size[MAXN],pre[MAXN];
 25 int que[MAXN],ql,qr,ans[MAXN];
 26 
 27 struct node{
 28     int add;
 29 }a[MAXN*4];
 30 
 31 inline int getint()
 32 {
 33        int w=0,q=0;
 34        char c=getchar();
 35        while((c<'0' || c>'9') && c!='-') c=getchar();
 36        if (c=='-')  q=1, c=getchar();
 37        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
 38        return q ? -w : w;
 39 }
 40 
 41 inline void dfs1(int x,int fa){
 42     father[x]=fa; size[x]=1;
 43     for(int i=first[x];i;i=next[i]) {
 44     int v=to[i]; if(v==fa) continue;
 45     deep[v]=deep[x]+1; dfs1(v,x);
 46     size[x]+=size[v]; if(size[v]>size[son[x]]) son[x]=v;
 47     }
 48 }
 49 
 50 inline void dfs2(int x,int fa){
 51     id[x]=++ecnt; pre[ecnt]=x; if(son[x]) top[son[x]]=top[x],dfs2(son[x],x);
 52     for(int i=first[x];i;i=next[i]) {
 53     int v=to[i]; if(v==fa || v==son[x]) continue;
 54     top[v]=v; dfs2(v,x);
 55     }
 56 }
 57 
 58 inline void update(int root,int l,int r){
 59     if(ql<=l && r<=qr) { a[root].add++; return ; }
 60     int mid=(l+r)/2; int lc=root*2,rc=lc+1;
 61     if(ql<=mid) update(lc,l,mid);  if(qr>mid) update(rc,mid+1,r);
 62 }
 63 
 64 inline void lca(int x,int y){
 65     int f1=top[x],f2=top[y];
 66     while(f1!=f2) {
 67     if(deep[f1]<deep[f2]) swap(f1,f2),swap(x,y);
 68     ql=id[f1]; qr=id[x]; update(1,1,n);
 69     x=father[f1]; f1=top[x];
 70     }
 71     if(deep[x]<deep[y]) swap(x,y);
 72     ql=id[y]; qr=id[x];  update(1,1,n);
 73 }
 74 
 75 inline void pushdown(int root,int l,int r){
 76     if(l==r) { ans[pre[l]]=a[root].add; return ; }
 77     int mid=(l+r)/2; int lc=root*2,rc=lc+1;
 78     a[lc].add+=a[root].add; a[rc].add+=a[root].add;
 79     pushdown(lc,l,mid); pushdown(rc,mid+1,r);
 80 }
 81 
 82 inline void work(){
 83     n=getint(); for(int i=1;i<=n;i++) que[i]=getint();
 84     int x,y;
 85     for(int i=1;i<n;i++) {
 86     x=getint(); y=getint();
 87     next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; 
 88     next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x;
 89     }
 90     deep[1]=0; dfs1(1,0);
 91     ecnt=0; top[1]=1; dfs2(1,0);
 92     for(int i=2;i<=n;i++) { lca(que[i-1],que[i]); }
 93     pushdown(1,1,n); for(int i=2;i<=n;i++)  ans[que[i]]--;
 94     for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
 95 }
 96 
 97 int main()
 98 {
 99   work();
100   return 0;
101 }

 

posted @ 2016-08-02 11:37  ljh_2000  阅读(230)  评论(0编辑  收藏  举报