3631: [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 #include<iostream>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<queue>
 10 #include<vector>
 11 #include<set>
 12 #define inf 1000000000
 13 #define maxn 300005
 14 #define maxm 300005*2
 15 #define eps 1e-10
 16 #define ll long long
 17 #define for0(i,n) for(int i=0;i<=(n);i++)
 18 #define for1(i,n) for(int i=1;i<=(n);i++)
 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 22 using namespace std;
 23 int read()
 24 {
 25     int x=0,f=1;char ch=getchar();
 26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 27     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 28     return x*f;
 29 }
 30 struct edge{
 31     int go,next;
 32 }e[maxm];
 33 int head[maxn],w[maxn],top[maxn],fa[maxn],p[maxn],son[maxn],s[maxn],dep[maxn],a[maxn],tot,cnt;
 34 struct tree{
 35     int l,r,sum,lazy;
 36 }f[maxn*4];
 37  
 38 void pushup(int i){
 39     f[i].sum=(f[i*2+1].sum+f[i*2].sum);
 40 }
 41  
 42 void update(int i,int x)
 43 {
 44     f[i].sum+=x*(f[i].r-f[i].l+1);
 45     f[i].lazy+=x;
 46     return;
 47 }
 48  
 49 void pushdown(int i){
 50     if(f[i].lazy!=0){
 51         update(i*2,f[i].lazy);
 52         update(i*2+1,f[i].lazy);
 53         f[i].lazy=0;
 54         return;
 55     }
 56     else return;
 57 }
 58  
 59 void build(int i,int left,int right){
 60     int mid=(left+right)/2;
 61     f[i].lazy=0;f[i].sum=0;
 62     f[i].l=left;f[i].r=right;
 63     if(left==right){
 64         return;
 65     }
 66     build(i*2,left,mid);
 67     build(i*2+1,mid+1,right);
 68     pushup(i);
 69 }
 70  
 71 void add(int i,int left,int right,int v){
 72     int mid=(f[i].l+f[i].r)/2;
 73     if(f[i].l==left&&f[i].r==right){
 74         update(i,v);
 75         return;
 76     }
 77     pushdown(i);
 78     if(mid>=right)add(i*2,left,right,v);  
 79     else if(mid<left)add(i*2+1,left,right,v);
 80     else add(i*2,left,mid,v),add(i*2+1,mid+1,right,v);
 81     pushup(i);
 82 }
 83  
 84 int query(int i,int left,int right) {
 85         int mid=(f[i].l+f[i].r)/2;
 86         if(f[i].l==left&&f[i].r==right) return f[i].sum;
 87         pushdown(i);
 88         if(mid>=right) return query(i*2,left,right);
 89         if(mid<left) return query(i*2+1,left,right);
 90         return (query(i*2,left,mid)+query(i*2+1,mid+1,right));
 91 }
 92 
 93 void insert(int u,int v){
 94     e[++tot].go=v;e[tot].next=head[u];head[u]=tot;
 95 }
 96 void ins(int u,int v){
 97     insert(u,v);insert(v,u);
 98 }
 99 void dfs(int x){
100     s[x]=1;
101     for(int y=son[x]=0,i=head[x];i;i=e[i].next){
102         if(dep[y=e[i].go]==0){
103             dep[y]=dep[x]+1;fa[y]=x;dfs(y);
104             s[x]+=s[y];if(s[y]>s[son[x]])son[x]=y;
105         }
106     }
107 }
108 void dfs2(int x,int chain){
109     p[x]=++cnt;top[x]=chain;
110     if(son[x])dfs2(son[x],chain);
111     for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
112         if(y!=fa[x]&&y!=son[x])dfs2(y,y);
113 }
114 int solvesum(int x,int y){
115     int ans=0;
116     while(top[x]!=top[y]){
117         if(dep[top[x]]<dep[top[y]])swap(x,y);
118         ans+=query(1,p[top[x]],p[x]);
119         x=fa[top[x]];
120     }
121     if(dep[x]>dep[y])swap(x,y);
122     ans+=query(1,p[x],p[y]);
123     return ans;
124 }
125 void solveadd(int x,int y){
126     while(top[x]!=top[y]){
127         if(dep[top[x]]<dep[top[y]])swap(x,y);
128         add(1,p[top[x]],p[x],1);
129         x=fa[top[x]];
130     }
131     if(dep[x]>dep[y])swap(x,y);
132     add(1,p[x],p[y],1);
133 }
134 int main(){
135     //freopen("input.txt","r",stdin);
136     //freopen("output.txt","w",stdout);
137     int n=read();dep[1]=1;
138     for1(i,n)a[i]=read();
139     for1(i,n-1){
140         int u=read(),v=read();
141         ins(u,v);
142     }
143     dfs(1);dfs2(1,1);  
144     build(1,1,n);
145     for(int i=2;i<=n;i++)
146         solveadd(a[i-1],a[i]);
147     for1(i,n)
148         w[i]=solvesum(i,i);
149     for(int i=2;i<=n;i++)w[a[i]]--;
150     for1(i,n)printf("%d\n",w[i]);
151     return 0;
152 }
View Code

 

posted @ 2016-05-22 10:30  HTWX  阅读(159)  评论(0编辑  收藏  举报