Fork me on GitHub 返回顶部

Atcoder AGC005 解题报告

\(A.\ STring\)

简要题意:

有一个字符串\(X\),对它进行操作。
该串只含\(S\)\(T\),凡是\(S\)\(T\)连在一起都要将它们一起去掉。
现在进行若干次操作直到该串中没有连在一起的\(ST\),问剩下的长度。

题目解法:

考虑用对顶栈模拟。
先将所有的字符串加入右栈中。
依次将一个字符从右栈中弹出,加入左栈。
如果在任意时刻,出现了左栈顶是\(S\)而右栈顶是\(T\),那么就两个栈都弹出栈顶。
容易发现这样一定可以将所有的\(ST\)删完。

\(B.\ Minimum\ Sum\)

简要题意:

给出一个排列,求所有的区间的最小值的和。

题目解法:

考虑用单调栈求出每一个数作为最小值能够向左和右拓展的距离\(l_i\)\(r_i\)
那么答案就是\(\sum_{i=1}^{N}P_i \times l_i \times r_i\)

\(C.\ Tree Restoring\)

简要题意:

给出一个序列,按要求构造一棵树。
满足树中,所有点到第\(i\)个点的距离最远是\(a_i\)

题目解法:

看到最远距离,就想直径。
根据常识(直径的定义),到一个点最远的点一定是直径的端点。
那么我们就能够发现,给出的序列排序之后,最小的数要等于最大的数的一半。
而且其他的数字要连续且每一个数字要出现两次。
特殊的,如果直径长度是偶数,那么最小的数只能出现一次。
如果直径长度是奇数,那么最小的数只能出现两次。
这么一番判断,就行了。

\(D.\ \sim K\ Perm\ Counting\)

简要题意:

如果一个排列\(P\)满足对于所有的\(i\)都有\(|P_i-i|\neq k\),则称排列\(P\)为合法的。现给出\(n\)\(k\),求有多少种合法的排列。
由于答案很大,请输出答案对\(924844033\)取模的结果。

题目解法:

拿到题目,考虑容斥。
考虑求出一个\(g_i\)表示至少有\(i\)个位置不满足要求的方案数。
那么答案\(Ans = \sum_{i=0}^{N}(-1)^i g[i]\)
我们建出一个二分图,上下两排都是\(N\)个点,其中上排代表下标,下排代表排列的值。
那么我们不满足要求就是要某一些位置\(|P_i - i| = k\),这样我们可以练出若干条链。
之后我们发现每一条链是类似的,所以我们只用考虑其中一条链。
\(f[i][j][0/1]\)表示某一条链,考虑了前\(i\)个点,选了\(j\)条边,而且最后的点那条向前的边选了没有的方案数。
之后我们就可以用背包求出\(g\)了。

\(E.\ Sugigma:\ The\ Showdown\)

简要题意:

有一个无向图,边分为红边和蓝边,两种边分别构成一棵树。两个人在两棵树上各一个点。
两人轮流移动,操作只有两个:走或不走。你只能走到与所在点相连的点上。
先手在红树上移动,后手在蓝树上移动。如果任意时刻两个人位于同一个点即可输出
红树需要最大化玩家的操作次数,蓝树需要最小化玩家的操作次数。
求最终操作次数的值,若游戏可以一直进行下去,那么输出\(-1\)

题目解法:

先考虑判断\(-1\)
容易发现,游戏能够一直进行,最后一定是某种循环。
而这种循环,通过手玩是可以\(get\)到的。
就是后手一直在\(B\)树上追先手,先手不动,等到后手快来的时候,跳一下,又离后手很远,之后在哪里等,之后再跳回来\(...\)如此循环。
那么判断\(-1\)就很简单了,就是将图按照后手的\(B\)树上的深度建树,如果先手能够在后手之前走到一个能一直进行上述过程的点,那么就是\(-1\)
其实不是\(-1\)就更简单了,那么先手就只能跳到后手的树中深度最远的点等后手了(因为在这个子树中不存在那种能绕后手的点)。

\(F.\ Many\ Easy\ Problems\)

简要题意:

给定一棵无根树,定义\(f(i)\),对于所有大小为\(i\)的点集,求出能够包含它的最小连通块大小之和。
对于\(i=1 \to n\)的所有\(i\),求出\(f(i)\)

题目解法:

披着\(F\)题外衣的普及题。。。
考虑将贡献放到每一个点上,那么就是要对于每一个点,求它被多少集合的最小联通块包含。
emm...后面不想写了。。。
之后就是用组合数算每一个点的贡献,之后用多项式统一计算就好了。

posted @ 2020-04-16 20:36  tacmon  阅读(203)  评论(0编辑  收藏  举报