modified: solutions/P17437.md
This commit is contained in:
1 parent
ec3c08099f
commit
38f5b1dede
1 file changed
+10
-19
+10
-19
@@ -35,24 +35,17 @@
|
|||||||
::::
|
::::
|
||||||
|
|
||||||
::::success[证明]
|
::::success[证明]
|
||||||
|
设全局最优中位数为 $y$。任何切法的中位数都不可能超过 $y$,所以只要证明:总有一种候选切法能使中位数达到 $y$。
|
||||||
|
|
||||||
设全局最优三块权值排序为 $x\le y\le z$,其中 $y$ 就是最优中位数。注意以下论证不依赖权值非负。
|
分两类看最优切法。
|
||||||
|
|
||||||
记第一刀切出的一侧为 $A$,另一侧为 $B$。若第二刀在 $A$ 内切出块 $a$,三块为 $a,A-a,B$;若在 $B$ 内切出块 $b$,三块为 $A,b,B-b$。由定义,对 $A$ 内任意可切块 $a$ 有 $dmin_A\le a\le dmax_A$;对 $B$ 内任意可切块 $b$ 有 $umin_B\le b\le umax_B$。
|
**两个切点互不为祖先。**
|
||||||
|
三块是两棵互不相交的子树和剩下的补集。若中位块是某棵子树,就把这棵子树作为第一刀,另一侧用最小或最大可切值切出另一棵子树,使另外两块分别落在 $y$ 的两边,中位数仍是 $y$。若中位块是补集,就取权值不小于 $y$ 的那棵子树作第一刀,再在另一侧切出剩下的子树,同样能让中位数达到 $y$。
|
||||||
|
|
||||||
分两类讨论:
|
**两个切点有祖先关系。**
|
||||||
|
三块是祖先外侧、中间夹层、后代子树。若中位块是后代,就取后代边作第一刀,在另一侧切出祖先外侧,用最小或最大可切值把中间夹层推到 $y$ 的另一边。若中位块是祖先外侧,就取祖先边作第一刀,在子树侧切出后代,同理。若中位块是中间夹层,则外侧和后代一个不大于 $y$、一个不小于 $y$,此时无论取祖先边还是后代边作第一刀,再在另一侧取合适的极值,都能让三块中至少两块不小于 $y$、至少两块不大于 $y$,中位数仍为 $y$。
|
||||||
1. **两个切点互不为祖先**。设两棵互不相交的子树为 $Q,R$,补集为 $P$,权和分别为 $p,q,r$。
|
|
||||||
- 若中位块是某棵子树(例如 $Q$,此时 $q=y$),取切出 $Q$ 的边为第一刀,则 $A=Q=y$,$B=P+R$,第二刀在 $B$ 内切出 $R$。若 $r\le y$,取 $umin_B\le r\le y$,则 $B-umin_B\ge B-r=P\ge y$,中位数为 $y$;若 $r\ge y$,取 $umax_B\ge r\ge y$,则 $B-umax_B\le P\le y$,中位数仍为 $y$。
|
|
||||||
- 若中位块是补集 $P$(此时 $p=y$),$q,r$ 一个不大于 $y$、一个不小于 $y$。取权值不小于 $y$ 的那棵子树对应的边为第一刀(不妨设为 $R$,则 $A=R\ge y$,$B=P+Q$),第二刀在 $B$ 内切出 $Q$。取 $umin_B\le q\le y$,则 $B-umin_B\ge B-q=P=y$,三块中位数不小于 $y$,由全局最优性为 $y$。
|
|
||||||
|
|
||||||
2. **两个切点有祖先关系**。设祖先边切出 $U$,后代边在 $U$ 内切出 $V$,三块为 $P=T\setminus U$、$Q=U\setminus V$、$R=V$,权和为 $p,q,r$。
|
|
||||||
- 若中位块是 $R$($r=y$),取后代边为第一刀,$A=R=y$,$B=P+Q$,第二刀在 $B$ 内切出 $P$。若 $p\le y$,取 $umin_B\le p\le y$,则 $B-umin_B\ge Q\ge y$;若 $p\ge y$,取 $umax_B\ge p\ge y$,则 $B-umax_B\le Q\le y$。中位数为 $y$。
|
|
||||||
- 若中位块是 $P$($p=y$),取祖先边为第一刀,$A=Q+R$,$B=P=y$,第二刀在 $A$ 内切出 $R$。若 $r\le y$,取 $dmin_A\le r\le y$,则 $A-dmin_A\ge Q\ge y$;若 $r\ge y$,取 $dmax_A\ge r\ge y$,则 $A-dmax_A\le Q\le y$。中位数为 $y$。
|
|
||||||
- 若中位块是 $Q$($q=y$),则 $p,r$ 一个不大于 $y$、一个不小于 $y$。若 $r\le y\le p$,取祖先边为第一刀,$A=Q+R$,$B=P$,第二刀在 $A$ 内切出 $R$,取 $dmin_A\le r\le y$,则 $A-dmin_A\ge Q=y$ 且 $B=P\ge y$,中位数不小于 $y$,故为 $y$;若 $p\le y\le r$,取后代边为第一刀,$A=R$,$B=P+Q$,第二刀在 $B$ 内切出 $P$,取 $umin_B\le p\le y$,则 $B-umin_B\ge Q=y$ 且 $A=R\ge y$,中位数亦为 $y$。
|
|
||||||
|
|
||||||
综上,全局最优中位数总可由“枚举一条边作为第一刀,再在另一侧取 $dmin/dmax$ 或 $umin/umax$”的四类候选之一达到。故最终枚举第一刀并检查四类候选即可。
|
|
||||||
|
|
||||||
|
所以,全局最优中位数一定能在“枚举第一刀,另一侧取 $dmin/dmax$ 或 $umin/umax$”这四类候选中出现。最终枚举第一刀并检查四类候选即可。
|
||||||
::::
|
::::
|
||||||
|
|
||||||
## 预处理子树最大、最小可切值
|
## 预处理子树最大、最小可切值
|
||||||
@@ -125,7 +118,7 @@ $$
|
|||||||
|
|
||||||
第二刀切出的 $a \in \{dmax_v, dmin_v\}$。
|
第二刀切出的 $a \in \{dmax_v, dmin_v\}$。
|
||||||
|
|
||||||
三块分别为 $a, A - a, B$,答案为 $median(t, A-t, B)$。
|
三块分别为 $a, A - a, B$,答案为 $median(a, A - a, B)$。
|
||||||
|
|
||||||
### 第二刀切在 $B$ 内部。
|
### 第二刀切在 $B$ 内部。
|
||||||
|
|
||||||
@@ -135,7 +128,7 @@ $$
|
|||||||
|
|
||||||
记录最大答案即可。
|
记录最大答案即可。
|
||||||
|
|
||||||
::::info[code]
|
::::success[code]
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
@@ -143,7 +136,6 @@ $$
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
int n; // 5e5
|
int n; // 5e5
|
||||||
vector<int> fri[500005];
|
vector<int> fri[500005];
|
||||||
int dep[500005];
|
|
||||||
int fa[500005];
|
int fa[500005];
|
||||||
long long sum[500005];
|
long long sum[500005];
|
||||||
long long dmin[500005], dmax[500005]; // down max / min
|
long long dmin[500005], dmax[500005]; // down max / min
|
||||||
@@ -158,7 +150,6 @@ long long median(long long x, long long y, long long z) {
|
|||||||
}
|
}
|
||||||
int noword;
|
int noword;
|
||||||
void dfs(int u) {
|
void dfs(int u) {
|
||||||
dep[u] = dep[fa[u]] + 1;
|
|
||||||
ord[++noword] = u;
|
ord[++noword] = u;
|
||||||
for (int v : fri[u]) {
|
for (int v : fri[u]) {
|
||||||
if (v == fa[u]) continue;
|
if (v == fa[u]) continue;
|
||||||
@@ -251,4 +242,4 @@ signed main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
::::
|
::::
|
||||||
Reference in new issue
Block a user