Xiejiadong edited 6 年前
月赛参赛人数重回一千。撒花。
牛逼网友 oxx1108 又来出月赛了,但愿不是惨案。事实证明就是惨案。
下个月你们还能做到牛逼网友 oxx1108 出的题目,题目非常“友好”。(疯狂暗示)
Xiejiadong :好像每次我主导的月赛题解都特别长啊?可能是我废话比较多。
kblack :你们这出的 Div1 啊?
oxx1108 :感觉我就是一股清流, A 和 C 怎么都几乎没人跟我做法一样。
# | Tag | Idea | Developer | Tester |
---|---|---|---|---|
A | 构造 | Xiejiadong | Xiejiadong | oxx1108 Kilo_5723 |
B | 贪心 | Xiejiadong | Xiejiadong | oxx1108 Weaver_zhu |
C | 暴力 剪枝 | Xiejiadong | Xiejiadong | oxx1108 Weaver_zhu |
D | 数学 | Kilo_5723 | Kilo_5723 | Xiejiadong Weaver_zhu |
E | 树形dp | oxx1108 | Kilo_5723 | Xiejiadong Kilo_5723 |
构造题。解法非常多。
首先无解是唬你的,不存在无解的情况,可以很容易的证明,这里省去。
随机。
我们首先按照顺序三个三个分组,发现其中有一些是不满足要求的,于是考虑随机交换。
每次随机选择一组的第二个和另一组的第三个进行交换。
但是我把我自己卡掉了。
大家有更好的随机策略可以在评论区交流。
by oxx1108
从钝角出发,很直接的就想到构造两条短边和一条长边,只要使得短边的和与长边的差值很小就行。
又是
详细思路与证明可见评论区 10175101159 的分享。
通过解法1,我们发现对于每一组的第一个默认为
于是我们默认每一组的第一个数,来构造后面两个数。
首先,如果长度为
我们考虑从
这样一来,空出了
而对于
同样我们默认每组的第一个是
第二数选择当前没有被选择的数中最小的一个数,然后在剩下的数中二分寻找一个满足要求的最小数。
可以证明,这样的构造方法是满足要求的。
oxx1108 :套路的构造题,但是好像大家都觉得有点难?可能更适合放数学竞赛里吧……
签到题。
考虑最旁边的两个数,如果相等,直接略过他们,因为他们本身已经是回文了;
如果不相等,那么一定是较小的一个要向内合并,合并完以后继续比较当前最旁边的两个数。
显然这样的策略是最优的,最坏的情况就是,所有的数合并成一个数,一个数显然满足回文。
一种解法是显然的,我们的线段树建法,决定了线段树要么左右孩子等大,要么左孩子比右孩子大
对于一个线段树上的结点
这样一来,我们就可以直接暴力了。这样的暴力还不足以通过这道题目。
一些剪枝是必要的。
比如可行性剪枝
比如
比如特判
当然验题人 oxx1108 提出了一种更加精妙(手动划去)愚蠢的解法:
本质就是枚举所有可行的
首先,可以明确的是如果
方法一: 显然在该层线段个数一定为二的次幂,而每个线段长度一定为
方法二: 由于在该层,每个线段长度必为
利用类似性质应该有很多方法能过此题。
由于出题人本身技艺不佳,原本的题目是限制了
牛逼网友 oxx1108 在验题中的代码速度经过优化,甚至跑得比 std 快近
验题人一致认为本场月赛难度太高,又无法严格证明,于是,限制条件又加上了。
oxx1108 :递归暴力过不去,只能想野鸡做法了,结果野鸡做法比std跑得还快。如果有会证明野鸡做法正确性的可以交流一下,想了好久不知道为什么可以跑那么快。
签到题。
要想清楚还是比较麻烦的,大力猜测结论与奇偶性相关,就稳了。
结论是:如果
下面我们定义距离为两个玩家棋子间的曼哈顿距离,我们发现,每个玩家每个回合开始时距离的奇偶性是保持不变的,因为每个玩家移动时,距离的奇偶性都会发生改变,而到下个玩家移动时,奇偶性就会变回来。由于只有回合开始时距离为
接着,证明不存在平局情况:
因为一方不可能输,所以想要赢,只要不断拉近距离即可。先来简单证明双方距离不会变大:
无论守方如何移动,双方的距离都最多增加
因此,想要平局,守方只能保证距离不变。为了不拉近距离,守方肯定会选择远离一方的方向移动。双方之间的位置关系有两种可能:第一种,不在同一行也不在同一列;第二种,在同一行或同一列。
先来讨论第一种情况,我们假设守方在攻方的左上方,那守方只能向左或向上走,否则就会主动拉近距离。此时,攻方只要重复守方的移动即可。因为守方在攻方的左上方,因此如果守方一直向左或向上,肯定比攻方先碰到边界,最终被逼到边角,不得不向右或下方移动,不可能保证距离一直不变。
接着讨论第二种情况,我们假设守方在攻方的正上方,如果守方向左或向右,那攻方只要向上走,就会在不增加距离的情况下变成第一种情况,因此守方只能向上走,但这么走也早晚会碰到边界,最后不得不将情况变成第一种情况。
于是,我们知道两个棋子之间的距离只可能减小。因此,不存在平局情况,回合开始时距离为奇数的一方必胜。
ultmaster :牛逼啊?
Xiejiadong :由于楼上不信,现学了博弈搜索,莽了一发。
给出 dp 实现的伪代码:
其中第五第六行为背包过程,由于只需要输出答案,因此保留 max 值即可。
F 的含义是不包含子树根结点,其祖先已取的集合为 A 时最大取值,G 的含义是包含子树根结点。
由于一定是祖先中最近的结点最优,因此可以用最近的祖先/距离来代替集合 A,注意空集时候的问题,最终复杂度
Xiejiadong :这个树形 dp 也太难了。想出来了也写不出来。何况我也想不出来。
oxx1108 :这是从某篇正在研究的paper里提取出来的问题,原本还需要套一个虚树,但是太胖了虚树部分就扔掉了(原来计划放校赛里卡 Xiejiadong ,现在校赛里应该是一堆“友好”的题了)。如果有更好的解法或者推广(到 DAG ,改成无根树等)欢迎交流。
Kilo_5723 :这题两个星期前就给我了,终于在比赛当天中午验出来了。
解法四似乎会超时(本人TLE11好几发了),对于最坏1e6的情况,剩余数组里有2e6规模的数字,二分需要20次的查找到(最坏),而解法二的用时最低的是0.235s,乘上这20次的二分查找次数就有4s多了,而且看了其他AC的代码,也没有用解法四AC的
非常感谢你分享自己的做法,其实你的构造方式和解法二(我的构造方式)是一样的,主要逻辑也是一致的。只是由于我写的过于简略,可能大家都没看懂。
也很感谢你够花那么长时间来思考月赛题目,其实每一场都会有一些题有很多的思路解法,如果感兴趣深入探究都可以发现出一些很奇妙的方法。
很欣赏你思考问题的精神!
谢谢!!!重新整了一下
我尝试对特例 构造找规律 容易满足,但 比较困难 ,枚举注意到 比较特殊,它所在的组另两数必相邻 个数分属 组,每组另外两个数恰好满足 (尽可能间隔拉大) 所在的组另两数相差 , 所在的组另两数相差 ,以此类推
个数放前面( )呢还是把奇数的 个数放前面( ) )而言,因为 增大时, 和 的距离不断变大 的较小要求放在前面,所以先配偶数 ,再配奇数 即 的条件下恒成立; 即 的条件下恒成立; 和 满足 和 即可 )就完成了证明 个数中奇数偶数分别有多少就能确定边界了 输出到 会比反过来更容易定界:
试了三四种策略发现
于是考虑先满足
前面尝试还发现,如果较小的两个数取的太小,最后一组三个数很容易相邻,难以保证
很自然地想到让最小的
也就是说
那么每组较大的两个数的相对位置关系形如下图中每行的两个
下一步就是把这么多行并成一行,容易发现可以把第一行嵌入第三行,再嵌入第五行,以此类推
同理把第二行嵌入第四行,再嵌入第六行,以此类推(但这里多留了个空隙,待会会被更好的方案否决)
这样一种初步方案就被构造出来了:
其中奇数部分为了去掉前述空隙,采用了偶数部分的图案就解决了
稍微试了一下,貌似可行
但这样构造马上让我思考,偶数的
想到对第一个奇偶数(
所以贪心地只需要把满足
到此为止,我们就只需要说明这种构造的正确性了,证明是显然的
偶数部分证明
展开,只要证
而这在
奇数部分证明
展开,只要证
而这在
这表明只要证奇数偶数的第一行,即
而相邻两个自然数平方差随着数的增加而增大,只要验证
最后单独计算说明只有偶数没有奇数的情况(
然后确定一下前
实际操作中发现从