[JLOI2014]松鼠的新家

题目描述

松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。

松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致**重复走很多房间,懒惰的**不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

**是个馋家伙,立马就答应了。现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。

因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:
5
1 4 5 3 2
1 2
2 4
2 3
4 5
输出样例#1:
1
2
1
2
1

说明

2<= n <=300000

树上差分:

和区间[l,r]+1的方法d[x]++,d[y+1]--差不多

拓展到树上,x到y+1,显然可以树链剖分,但树上差分更快

方法d[x]++,d[y]++,d[Lca]--,d[fa(Lca)]--

Lca减1是因为重复

还有最后求完和后,要把每一条路的终点-1,因为算了2次

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 struct Node
  7 {
  8   int next,to;
  9 }edge[600001];
 10 int num,head[300001],dep[300001],fa[300001][19],d[300001],a[300001],n;
 11 void add(int u,int v)
 12 {
 13   num++;
 14   edge[num].next=head[u];
 15   head[u]=num;
 16   edge[num].to=v;
 17 }
 18 void dfs(int x,int pa)
 19 {int i;
 20   dep[x]=dep[pa]+1;
 21   for (i=1;i<=18;i++)
 22     {
 23       fa[x][i]=fa[fa[x][i-1]][i-1];
 24     }
 25   for (i=head[x];i;i=edge[i].next)
 26     {int v=edge[i].to;
 27       if (v!=pa)
 28     {
 29       fa[v][0]=x;
 30       dfs(v,x);
 31     }
 32     }
 33 }
 34 void dfs_sum(int x,int pa)
 35 {int i;
 36    for (i=head[x];i;i=edge[i].next)
 37     {int v=edge[i].to;
 38       if (v!=pa)
 39     {
 40       dfs_sum(v,x);
 41       d[x]+=d[v];
 42     }
 43     }
 44 }
 45 int LCA(int x,int y)
 46 {int i;
 47   if (dep[x]<dep[y]) swap(x,y);
 48   for (i=18;i>=0;i--)
 49     if ((1<<i)<=dep[x]-dep[y])
 50       {
 51     x=fa[x][i];
 52       }
 53   if (x==y) return x;
 54   if (x!=y)
 55     {
 56       for (i=18;i>=0;i--)
 57     {
 58       if (fa[x][i]!=fa[y][i])
 59         {
 60           x=fa[x][i];
 61           y=fa[y][i];
 62         }
 63     }
 64       x=fa[x][0];
 65       y=fa[y][0];
 66     }
 67   return x;
 68 }
 69 int main()
 70 {int i,x,y;
 71   cin>>n;
 72   for (i=1;i<=n;i++)
 73     {
 74       scanf("%d",&a[i]);
 75     }
 76   for (i=1;i<=n-1;i++)
 77     {
 78       scanf("%d%d",&x,&y);
 79       add(x,y);
 80       add(y,x);
 81     }
 82   dfs(1,0);
 83   for (i=2;i<=n;i++)
 84     {
 85       int x=LCA(a[i-1],a[i]);
 86       d[a[i-1]]++;
 87       d[a[i]]++;
 88       d[x]--;
 89       d[fa[x][0]]--;
 90     }
 91   dfs_sum(1,0);
 92   for (i=2;i<=n;i++)
 93     {
 94       d[a[i]]--;
 95     }
 96   for (i=1;i<=n;i++)
 97     {
 98       printf("%d\n",d[i]);
 99     }
100 }

 

posted @ 2017-08-31 13:38  Z-Y-Y-S  阅读(311)  评论(0编辑  收藏  举报