【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 }
时间: 2024-10-23 20:34:40

【bzoj1782】[Usaco2010 Feb]slowdown 慢慢游的相关文章

[BZOJ1782][Usaco2010 Feb]slowdown 慢慢游

1782: [Usaco2010 Feb]slowdown 慢慢游 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 770  Solved: 494 [Submit][Status][Discuss] Description 每天Farmer John的N头奶牛(1 <= N <= 100000,编号1-N)从粮仓走向他的自己的牧场.牧场构成了一棵树,粮仓在1号牧场.恰好有N-1条道路直接连接着牧场,使得牧场之间都恰好有一条路径相连.第i条路连接着

BZOJ 1782: [Usaco2010 Feb]slowdown 慢慢游( BIT + dfs )

orz...hzwer 对着大神的 code 看 , 稍微理解了. 考虑一只牛到达 , 那它所在子树全部 +1 , 可以用BIT维护 ----------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector

1782: [Usaco2010 Feb]slowdown 慢慢游

1782: [Usaco2010 Feb]slowdown 慢慢游 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 570  Solved: 346[Submit][Status][Discuss] Description 每天Farmer John的N头奶牛(1 <= N <= 100000,编号1…N)从粮仓走向他的自己的牧场.牧场构成了一棵树,粮仓在1号牧场.恰好有N-1条道路直接连接着牧场,使得牧场之间都恰好有一条路径相连.第i条路连接着A_

2015: [Usaco2010 Feb]Chocolate Giving

2015: [Usaco2010 Feb]Chocolate Giving Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 269  Solved: 183[Submit][Status] Description Farmer John有B头奶牛(1<=B<=25000),有N(2*B<=N<=50000)个农场,编号1-N,有M(N-1<=M<=100000)条双向边,第i条边连接农场R_i和S_i(1<=R_i&

bzoj2015[Usaco2010 Feb]Chocolate Giving*

bzoj2015[Usaco2010 Feb]Chocolate Giving 题意: n点m边无向图,有k头奶牛要送礼,它必须去农场(1号节点)拿礼物然后到目的地送.问每只奶牛的最短距离.n≤50000 题解: 以1号节点为源点spfa求一次最短路即可(反正是无向边). 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #defi

bzoj2014[Usaco2010 Feb]Chocolate Buying*

bzoj2014[Usaco2010 Feb]Chocolate Buying 题意: n种巧克力,每种有个单价和最多能买几块,问有B块钱一共最多能买几块.n≤100000 题解: 贪心,按单价排序. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define ll long long 5 #define inc(i,j,k) for(int i=j;i<=k;i++)

BZOJ 2015: [Usaco2010 Feb]Chocolate Giving( 最短路 )

裸最短路.. ------------------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #define rep( i , n ) for( int i = 0 ; i <

BZOJ 2015 Usaco2010 Feb Chocolate Giving

2015: [Usaco2010 Feb]Chocolate Giving Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 533  Solved: 348[Submit][Status][Discuss] Description Farmer John有B头奶牛(1<=B<=25000),有N(2*B<=N<=50000)个农场,编号1-N,有M(N-1<=M<=100000)条双向边,第i条边连接农场R_i和S_i(1

[Usaco2010 Feb]Chocolate Giving 最短路dijkstra+堆优化

本人水平有限,题解不到为处,请多多谅解 本蒟蒻谢谢大家观看 题目:传送门 最短路板子题:迪杰斯特拉+堆优化 注意:因为我建的是大根堆,所以要将距离取负,再存入大根堆堆中,这样队首就是最小值 直接套模板即可 code: 1 #include<bits/stdc++.h> 2 #define inf 0x3f3f3f3f 3 #pragma GCC optimize(3) 4 const int N=50005; 5 const int M=200002; 6 using namespace st