AGC-058
Atcoder Grand Contest 058
队友说板刷 agc 是最好的训练方法之一,于是我来了
A - Make it Zigzag
题意:给你一个长度为 \(2n\) 的排列,你最多可以做 \(n\) 次交换相邻元素的操作,最后要满足
题解:
感觉我的思路有点蠢(
先把数列差分,即 \(p_i\) 变成 \(p_{i+1}-p_i\) 那么我们的目标数列满足正负交替出现即可
考虑一个操作之后差分数列会变成什么,例如交换 \(x\) 和 \(x+1\) (简称操作 \(x\) )
差分数列 \(p_{x-1},p_x,p_{x+1}\) 会变成 \((p_{x-1}+p_x),-p_x,(p_x+p_{x+1})\)
那么可以这么操作,从前往后考虑,遇到第一个正负号不对的元素(显然它前一个元素正负号是对的)。
如果后面一个元素正负号不对,那就操作它与后一个元素绝对值更大的那一个
如果后面一个元素正负号是对的,那就操作它自己
这么做的话,它自己和它前后元素的正负号都能变成正确的。然后以此类推继续往后考虑。
然后就做完了
B - Adjacent Chmax
题意:给定一个排列,操作为将相邻两个元素变成他们中较大的那一个,你可以做任意次操作,问操作完了的排列会有多少种
题解:首先,结果的数字一定是成段出现的,不可能一个数字出现了两段,一定是连续的一段。每个数字有它能够覆盖的区间。
然后关键在于设状态,我设的是 \(f[i][j]\) 表示前 \(i\) 个位置已经确定,第 \(i\) 个位置放的是 \(j\) 。
讨论这个状态可以转移到哪些状态:
如果可以转移到 \(f[i+1][k]\)
分情况讨论
-
若 \(j\) 的初始位置在 \(i\) 之前,\(k\) 只需满足下列任意一个条件
- \(k=j\)
- \(k\) 的初始位置更靠近 \(i\) ,且 \(k<j\) ,且 \(k\) 可以覆盖到 \(i\) 位置
-
若 \(j\) 的初始位置在 \(i\) 之后,\(k\) 只需满足下列任意一个条件
- \(k=j\)
- \(k\) 的初始位置更远离 \(i\) ,且 \(k>j\) ,且 \(k\) 可以覆盖到 \(i\) 位置
然后有技巧的转移,就做完了
C - Planar Tree
题意:
有 \(n\) 个点围成了一个圈,点权只有1,2,3,4。只有点权差为 \(1\) 的点可以连边。现在要求你要把这 \(n\) 个点连成一颗树,并且边在平面上不能相交,问你是否有合法方案,输出 \(yes\) 或 \(no\) 。
题解:
首先,相邻的权值相同的点显然可以合并成一个点,因为只要他们可以连向同一个目标。
观察发现 1 只能和 2 相连,4 只能和 3 相连。那么我们直接合并上去,具体地,比如 1211222122112 就合并成了 2
这两种合并完了之后,考虑如何把剩下的 1 和 4 合并到 2 和 3 上去
分析新的环长什么样子,考虑新环上的 2 和 3 出现的位置
-
单个出现,夹在两个 1 或 两个 4 中间,如 131,1313131
-
连续交替出现,夹在 1 和 4 的中间,如 1 323232 4 23 1 4
先考虑第一种情况,其实很可以把 1313131 缩成单点 1 ,因为这些点都可以连向同一个目标
那么缩完之后来考虑第二种情况,发现 2 和 3 被绑定了,把连续的 2 和 3 连上。现在就很简单了,可以这么构造,挨个考虑 1 和 4 的点,连向离其距离最近的 23(32) 比如 1 就连向 23 中的 2,然后把这三个点删掉(注意是删掉,不是合并,因为会影响后面的点算距离)
最后如何能把所有点删完,或者只剩下 2 3 那么就一定有解
——
待更…