[BZOJ] 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2246 Solved: 1148
[Submit][Status][Discuss]
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
1 4 5 3 2
1 2
2 4
2 3
4 5
Sample Output
1
2
1
2
1
2
1
2
1
HINT
2<= n <=300000
Source
Analysis
树上差分的例题 qwq
无非是树上的某一条路径点权集体+1s
那么树上差分解决
心情很差qwq不写教程了
需要注意的是,题目有一个要求:每次移动的终点权值-1s
Code
1 #include<cstdio> 2 #include<iostream> 3 #define maxn 303030 4 using namespace std; 5 6 int depth[maxn],val[maxn],n,arr[maxn],fa[maxn][20]; 7 8 struct edge{ 9 int from,v; 10 }e[maxn*2]; 11 int tot,first[maxn]; 12 void insert(int u,int v){ 13 tot++; e[tot].from = first[u]; e[tot].v = v; 14 first[u] = tot; 15 } 16 17 void dfs(int now){ 18 for(int i = first[now];i;i = e[i].from){ 19 int v = e[i].v; 20 if(v != fa[now][0]){ 21 depth[v] = depth[now]+1; 22 fa[v][0] = now; 23 dfs(v); 24 } 25 } 26 } 27 28 void dfs2(int now){ 29 for(int i = first[now];i;i = e[i].from){ 30 int v = e[i].v; 31 if(v != fa[now][0]){ 32 dfs2(v); 33 val[now] += val[v]; 34 } 35 } 36 } 37 38 void Init(){ 39 for(int i = 1;i <= 18;i++) 40 for(int j = 1;j <= n;j++) 41 fa[j][i] = fa[fa[j][i-1]][i-1]; 42 } 43 44 int LCA(int u,int v){ 45 if(depth[u] < depth[v]) swap(u,v); 46 for(int i = 18;i > -1;i--) 47 if(depth[fa[u][i]] >= depth[v]) 48 u = fa[u][i]; 49 if(u == v) return u; 50 for(int i = 18;i > -1;i--) 51 if(fa[u][i] != fa[v][i]) 52 u = fa[u][i],v = fa[v][i]; 53 return fa[u][0]; 54 } 55 56 int main(){ 57 scanf("%d",&n); 58 59 for(int i = 1;i <= n;i++) 60 scanf("%d",&arr[i]); 61 for(int i = 1;i < n;i++){ 62 int x,y; scanf("%d%d",&x,&y); 63 insert(x,y); insert(y,x); 64 }depth[1] = 1; dfs(1); 65 Init(); 66 67 for(int i = 1;i < n;i++){ 68 int anc = LCA(arr[i],arr[i+1]); 69 if(anc == arr[i]){ 70 val[fa[anc][0]]--,val[arr[i+1]]++; 71 }else if(anc == arr[i+1]){ 72 val[fa[anc][0]]--,val[arr[i]]++; 73 }else{ 74 val[fa[anc][0]]--,val[anc]--; 75 val[arr[i]]++,val[arr[i+1]]++; 76 }val[fa[arr[i+1]][0]]++,val[arr[i+1]]--; 77 // for(int i = 0;i <= n;i++) printf("%d ",val[i]);cout << endl; 78 }dfs2(1); 79 80 for(int i = 1;i <= n;i++) printf("%d\n",val[i]); 81 82 return 0; 83 }
转载请注明出处 -- 如有意见欢迎评论