首页 > 代码库 > 【bzoj1782】[Usaco2010 Feb]slowdown 慢慢游
【bzoj1782】[Usaco2010 Feb]slowdown 慢慢游
题目描述
每天Farmer John的N头奶牛(1 <= N <= 100000,编号1…N)从粮仓走向他的自己的牧场。牧场构成了一棵树,粮仓在1号牧场。恰好有N-1条道路直接连接着牧场,使得牧场之间都恰好有一条路径相连。第i条路连接着A_i,B_i,(1 <= A_i <= N; 1 <= B_i <= N)。奶牛们每人有一个私人牧场P_i (1 <= P_i <= N)。粮仓的门每次只能让一只奶牛离开。耐心的奶牛们会等到他们的前面的朋友们到达了自己的私人牧场后才离开。首先奶牛1离开,前往P_1;然后是奶牛2,以此类推。当奶牛i走向牧场P_i时候,他可能会经过正在吃草的同伴旁。当路过已经有奶牛的牧场时,奶牛i会放慢自己的速度,防止打扰他的朋友。 考虑如下的牧场结构(括号内的数字代表了牧场的所有者)。
输入
* 第1行 : 一个正整数N * 第2…N行: 第i+1行包括一对正整数A_i,B_i * 第N+1..N+N行: 第 N+i行 包括一个正整数: P_i
输出
* 第一行到第N行:第i行表示第i只奶牛需要被放慢的次数
样例输入
5
1 4
5 4
1 3
2 4
4
2
1
5
3
样例输出
0
1
0
2
1
题解
树链剖分+线段树模板题,单点修改区间查询。
1 #include <cstdio> 2 #define lson l , mid , x << 1 3 #define rson mid + 1 , r , x << 1 | 1 4 int head[100001] , to[200001] , next[200001] , cnt; 5 int fa[100001] , deep[100001] , bl[100001] , si[100001] , pos[100001] , tot; 6 int sum[400001] , n , place[100001]; 7 void add(int x , int y) 8 { 9 to[++cnt] = y; 10 next[cnt] = head[x]; 11 head[x] = cnt; 12 } 13 void dfs1(int x) 14 { 15 int i; 16 si[x] = 1; 17 for(i = head[x] ; i ; i = next[i]) 18 { 19 if(to[i] != fa[x]) 20 { 21 fa[to[i]] = x; 22 deep[to[i]] = deep[x] + 1; 23 dfs1(to[i]); 24 si[x] += si[to[i]]; 25 } 26 } 27 } 28 void dfs2(int x , int c) 29 { 30 int k = 0 , i; 31 bl[x] = c; 32 pos[x] = ++tot; 33 for(i = head[x] ; i ; i = next[i]) 34 if(to[i] != fa[x] && si[to[i]] > si[k]) 35 k = to[i]; 36 if(k) 37 { 38 dfs2(k , c); 39 for(i = head[x] ; i ; i = next[i]) 40 if(to[i] != fa[x] && to[i] != k) 41 dfs2(to[i] , to[i]); 42 } 43 } 44 void pushup(int x) 45 { 46 sum[x] = sum[x << 1] + sum[x << 1 | 1]; 47 } 48 void update(int p , int a , int l , int r , int x) 49 { 50 if(l == r) 51 { 52 sum[x] += a; 53 return; 54 } 55 int mid = (l + r) >> 1; 56 if(p <= mid) update(p , a , lson); 57 else update(p , a , rson); 58 pushup(x); 59 } 60 int query(int b , int e , int l , int r , int x) 61 { 62 if(b <= l && r <= e) 63 return sum[x]; 64 int mid = (l + r) >> 1 , ans = 0; 65 if(b <= mid) ans += query(b , e , lson); 66 if(e > mid) ans += query(b , e , rson); 67 return ans; 68 } 69 int solve(int x) 70 { 71 int ans = 0; 72 while(bl[x] != 1) 73 { 74 ans += query(pos[bl[x]] , pos[x] , 1 , n , 1); 75 x = fa[bl[x]]; 76 } 77 ans += query(1 , pos[x] , 1 , n , 1); 78 return ans; 79 } 80 int main() 81 { 82 int x , y , i; 83 scanf("%d" , &n); 84 for(i = 1 ; i < n ; i ++ ) 85 { 86 scanf("%d%d" , &x , &y); 87 add(x , y); 88 add(y , x); 89 } 90 dfs1(1); 91 dfs2(1 , 1); 92 for(i = 1 ; i <= n ; i ++ ) 93 { 94 scanf("%d" , &x); 95 printf("%d\n" , solve(x)); 96 update(pos[x] , 1 , 1 , n , 1); 97 } 98 return 0; 99 }
【bzoj1782】[Usaco2010 Feb]slowdown 慢慢游
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。