From 1dedc9f79d26d5b279c62dd827ac2a2b1c525e09 Mon Sep 17 00:00:00 2001 From: hanyixuanten Date: Thu, 29 Oct 2026 08:26:18 +0000 Subject: [PATCH] new file: P2982.cpp --- P2982.cpp | 64 +++++++++++++++++++++++++++++++++ P2982.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 P2982.cpp create mode 100644 P2982.md diff --git a/P2982.cpp b/P2982.cpp new file mode 100644 index 0000000..8509cd9 --- /dev/null +++ b/P2982.cpp @@ -0,0 +1,64 @@ +#include +#define int long long +using namespace std; +int n; +vector fri[100005]; +int p[100005]; +int dfn[100005]; +int cnt[100005]; +int nowdfn; +struct SEG{ + int num[400005], lt[400005]; + void pd(int now, int nl, int nr) { + int nmid = (nl + nr) >> 1; + num[now * 2] += lt[now] * (nmid - nl + 1); + num[now * 2 + 1] += lt[now] * (nr - nmid); + lt[now * 2] += lt[now]; + lt[now * 2 + 1] += lt[now]; + lt[now] = 0; + } + void pu(int now) {num[now] = num[now * 2] + num[now * 2 + 1];} + void add(int now, int nl, int nr, int l, int r, int nn) { + if(nl > r || nr < l) return; + if(l <= nl && nr <= r) { + num[now] += nn * (nr - nl + 1); + lt[now] += nn; + return; + } + int nmid = (nl + nr) >> 1; + add(now * 2, nl, nmid, l, r, nn); + add(now * 2 + 1, nmid + 1, nr, l, r, nn); + pu(now); + } + int query(int now, int nl, int nr, int l, int r) { + if(nl > r || nr < l) return 0; + if(l <= nl && nr <= r) return num[now]; + int nmid = (nl + nr) >> 1; + pd(now, nl, nr); + return query(now * 2, nl, nmid, l, r) + query(now * 2 + 1, nmid + 1, nr, l, r); + } +}seg; +void dfs(int now, int from) { + cnt[now] = 1; + dfn[now] = ++nowdfn; + for(int i : fri[now]) { + if(i == from) continue; + dfs(i, now); + cnt[now] += cnt[i]; + } +} +signed main() { + scanf("%lld", &n); + for(int i = 1, u, v; i < n; ++i) { + scanf("%lld%lld", &u, &v); + fri[u].push_back(v); + fri[v].push_back(u); + } + dfs(1, 0); + for(int i = 1; i <= n; ++i) { + scanf("%lld", &p[i]); + printf("%lld\n", seg.query(1, 1, n, dfn[p[i]], dfn[p[i]])); + seg.add(1, 1, n, dfn[p[i]], dfn[p[i]] + cnt[p[i]] - 1, 1); + } + return 0; +} \ No newline at end of file diff --git a/P2982.md b/P2982.md new file mode 100644 index 0000000..c275c1c --- /dev/null +++ b/P2982.md @@ -0,0 +1,105 @@ +# P2982 [USACO10FEB] Slowing down G + +## 题目描述 + +每天,Farmer John 的 $N$ $(1 \le N \le 100{,}000)$ 头奶牛(方便地编号为 $1..N$)都会从牛棚走向各自的私人牧场。牧场形成一棵树,其中牛棚位于牧场 $1$。恰好有 $N-1$ 条无向路径连接这些牧场;直接相连的牧场之间恰好有一条路径。路径 $i$ 连接牧场 $A_i$ 和 $B_i$ $(1 \le A_i \le N, 1 \le B_i \le N)$。 + +奶牛 $i$ 拥有一个私人牧场 $P_i$ $(1 \le P_i \le N)$。牛棚的小门一次只能让一头奶牛出去,耐心的奶牛们会等待前一头奶牛到达她的私人牧场。首先,奶牛 $1$ 离开并走向牧场 $P_1$。接着奶牛 $2$ 离开并前往牧场 $P_2$,依此类推。 + +当奶牛 $i$ 走向 $P_i$ 时,她可能会经过已经有奶牛在进食的牧场。当一头奶牛出现在某个牧场时,奶牛 $i$ 在穿过该牧场时会比平时走得更慢,以避免打扰她的朋友。 + +```cpp +考虑以下牧场网络,其中括号中的数字表示牧场的主人。 + + 1 (3) + / \ + (1) 4 3 (5) + / \ +(2) 2 5 (4) + +首先,奶牛 1 走向她的牧场: + + 1 (3) + / \ + [1] 4* 3 (5) + / \ +(2) 2 5 (4) + +当奶牛 2 走向她的牧场时,她首先进入牛棚的牧场,即牧场 1。 +然后她绕过牧场 4 中的奶牛 1,最终到达自己的牧场。 + + 1 (3) + / \ + [1] 4* 3 (5) + / \ +[2] 2* 5 (4) + +奶牛 3 根本没走远——她在牛棚的牧场 #1 里闲逛。 + + 1* [3] + / \ + [1] 4* 3 (5) + / \ +[2] 2* 5 (4) + +奶牛 4 在前往牧场 5 的路上,必须在牧场 1 和 4 放慢速度: + + 1* [3] + / \ + [1] 4* 3 (5) + / \ +[2] 2* 5* [4] + +奶牛 5 因为在牧场 1 遇到奶牛 3 而放慢速度,然后进入自己的私人牧场: + + 1* [3] + / \ + [1] 4* 3*[5] + / \ +[2] 2* 5* [4] +``` + +FJ 想知道每头奶牛需要放慢多少次速度。 + +## 输入格式 + +- 第 1 行:一个整数 $N$。 +- 第 $2..N$ 行:第 $i+1$ 行包含两个以空格分隔的整数 $A_i$ 和 $B_i$。 +- 第 $N+1..N+N$ 行:第 $N+i$ 行包含一个整数 $P_i$。 + +## 输出格式 + +- 第 $1..N$ 行:第 $i$ 行包含奶牛 $i$ 需要放慢速度的次数。 + +## 输入输出样例 #1 + +### 输入 #1 + +``` +5 +1 4 +5 4 +1 3 +2 4 +4 +2 +1 +5 +3 + +``` + +### 输出 #1 + +``` +0 +1 +0 +2 +1 + +``` + +## 说明/提示 + +数据范围:$1 \leq A_i, B_i, P_i \leq N \leq 10^5$。 \ No newline at end of file