D. Let's Go Hiking
两人在序列上移动,Qingshan 只能往值更高的地方走,Daniel 只能往低处走。两人不能重叠,求 Qingshan 中有多少可以赢的位置。
分析
其实我们只用关注上升和下降的序列有多长,而不必关心它们具体是几。
如果 Qingshan 选边界上的坡,或者不选在坡顶,那么 Daniel 可以紧挨着它,从而必输。
如果 Qingshan 不选最长的坡,则 Danniel 可以选最长的坡,从而必输。
如果最长的坡存在没有公共最高点的两个,Danniel 可以避开 Qingshan 选,从而必输。
剩下的情况只有两种:
- 最长的坡只有一个,Qingshan 只能选在此坡坡顶,Danniel 可以选在靠近坡底的地方,使得两人碰面,从而必输。
- 最长的坡有两个且有公共最高点,Qingshan 选在坡顶,则可以选择避开 Danniel 下坡,从而必胜。
E. Garden of the Sun
在棋盘的格子中有不连续的 X,请连接使得其满足如下条件
X组成的图案是连通的。X组成的图案不存在环。
分析
X 不连续是一个比较强的性质。
构造类似 丰 字形的图案,横与横之间空两行,这样可以使得所有 X 都附在一条横上,且互相不连接。
接下来考虑如何把横连起来,可以发现只用在第一列、第二列中选一列进行连接即可。
F. BFS Trees
第一次补题补到 F 耶!什么时候才能在赛中做到 F 呢……
我们定义一个图上的生成树是以 $s$ 点为根的 BFS 树,当且仅当:对于任意的节点 $t$,$s\to t$ 在 BFS 树上的最短路等于图上的最短路。
定义 $f(i,j)$ 为根可以在 $i$ 且可以在 $j$ 的 BFS 树的个数,求所有的 $f(i,j) \bmod P$。
分析
题目有点绕,要好好的读一读。
注意到一个关键点:若 $i \to j$ 最短路有两条,而在生成树中只能有一条,则这些被断掉的节点到 $i,j$ 的最短路一定不能同时取到最小值,故答案不存在,即 $f(i,j) = 0$。
因此 $i \to j$ 只能有一条路。想象 $i$ 侧剩余的点按照到 $i$ 的距离分成层级,每个点 $k$ 满足 BFS 树条件的接入方式就是连到更近一层的点 $e$,即判据为
$$ dis(i, e) + 1 = dis(i, k)\ \text{且}\ dis(j, e) + 1 = dis(j, k) $$
注意到每次接入是独立的,答案即用乘法合并。
至于判最短路的条数,注意到 $dis(i,k) + dis(k,j) = dis(i,j)$ 即意味着 $k$ 在 $i \to j$ 的最短路上,计算满足条件的点数是否是 $dis(i,j) + 1$ 即可。
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
ll tans = 1, cnt = 0;
for (int k = 1; k <= n; k++) {
if (f[i][k] + f[j][k] == f[i][j]) {
cnt++;
} else {
int s = 0;
for (auto e : G[k]) {
s += f[i][e] + 1 == f[i][k] && f[e][j] + 1 == f[k][j];
}
tans = tans * s % P;
}
}
if (cnt != f[i][j] + 1) {
tans = 0;
}
ans[i][j] = ans[j][i] = tans;
}
}