2021“MINIEYE杯”中国大学生算法设计超级联赛(3)
好难啊,希望能补完。
拖了快一周了,补完了!
[1001 Bookshop]
solution
题面:给定一棵树,每个结点上有书,有价格,每次询问
做法:树先转换为序列来看,那么难的就是维护买书条件。
如果我们希望能连续一段段维护的话,那么残酷的一大一小的数据就能把段数卡到
如果我们希望能让if x>a then x-=a
成为一个较为可维护的运算的话,那么在经过长时间的构造无果后,我们就只能放弃了这个做法。
于是,综合处理所有询问是唯一的办法。显然可以让所有
然后我们冷静一下,发现直接这些可能改变大小顺序的数的个数之和是一个可接受的范围。于是我们完善了我们的做法。
对
至于放在树上,我们对树做一次重链剖分即可,每个询问就被拆成
1 | //2021.7.28 by ljz |
[1002 Destinations]
solution
题面:有
做法:注意到一个人的三种路径都是共起点的,那么他选择且只能选择其中一条。这样的话,如果我们无视掉人这个东西,仅仅只看
而选取无公共点的路径问题有一种常用解法是转成其对偶问题。于是我们构造矩阵:
其中,二元组
其加减定义为
于是原问题就转换成了
取其对偶问题,即
我们尝试理解
我们从树的深处往浅处确认点权,考虑当前点
方便说明,我们设满足端点的
假设已经确认好所有点的点权了,若有一个点
根据上述调整法,我们证明了贪心的正确性。
考虑维护这个贪心,直接暴力可以用重链剖分 + 线段树做到
1 | //2021.7.28 by ljz |
[1003 Forgiving Matching]
solution
题面:两个串匹配当且仅当长度相同,且对应位置上不同的字符
做法:字符串匹配,经典做法就是按每个字符算一遍,取
事实证明,FFT 把 NTT 在这种情况下暴打了,下面的 NTT 代码过不了,后来去贺了个 FFT 才能过。
1 | //2021.7.30 by ljz |
[1004 Game on Plane]
solution
题面:给定
做法:签到题。肯定想的是选尽量不同的斜率,随便维护一下即可。我实现的复杂度是
1 | //2021.7.30 by ljz |
[1005 Kart Race]
solution
题面:你有
做法:首先题意可以转换为选出若干个两两不可达的点使得在价值和最大的前提下,使字典序最小。
由于这是张平面有向无环图,我们可以利用
即在
于是题意就转换为选出一组点使得
不知道为什么评测机变奇怪了,不能忽略行末空格了,写的时候稍微注意点。
1 | //2021.7.31 by ljz |
[1006 New Equipments II]
solution
题面:有
做法:容易建出费用流模型,于是考虑模拟费用流。
由于这张图只有四层,而且是首尾两层与中间连接的时候才有费用,那么当我们选择一次配对
好像多了个这个
下面是带
1 | //2021.8.1 by ljz |
[1007 Photoshop Layers]
solution
题面:有
做法:每次询问找到最右边的
原来输出十六进制有特殊的方法啊,我完全不知道哎。
1 | //2021.7.27 by ljz |
[1008 Restore Atlantis II]
solution
题面:给
做法:考虑一维情况,我们发现随机数据下许多线段会被其他线段所包含,于是可用线段会比较少。同样地,二维也是如此。我们维护每个
然后有了这个条件怎么办呢?设线段组大小乘不同线段组的级别是
然而出题人卡了这个做法。我们发现本题没有修改只有询问,所以考虑 ST 表,这样就是
我们再优化,考虑四毛子算法,即分块,但分块大小为
实际上有点小卡常,感觉是我实现比较烂了。。。
1 | //2021.8.2 by ljz |
[1009 Rise in Price]
solution
题面:
做法:考虑一个暴力,
接下来想数据随机要怎么样,猜测一下就是二维都更大的数比较多,所以二元组集合大小比较小,暴力转移就好了。
复杂度
1 | //2021.8.1 by ljz |
[1010 Road Discount]
solution
题面:给
做法:生成树特殊边问题大部分的答案都具有凸性,于是我们考虑 wqs 二分。
对每个
注意到每次多一条边打折时,我们最多改变一条边,这可以很轻松证明,因为若改变的不止一条边的话,那么在之前改变的时候就会选择那条边了,由此反证说明最多改变一条边。那么我们总共会用到的边将只有不打折的最小生成树树边以及全打折的最小生成树的树边,于是我们可以将
注意到边权实际会很小,而斜率只会是
其实,就算我们不考虑 wqs 二分,直接维护每次只会更新一条边这个操作也是可行的。这等价于我们枚举一条边,然后找到两个连通块间的最短边。这两个操作可以一起来,即快速维护两棵树的图的不同连通块间的最大边权减最小边权。这个东西可以利用 LCT 维护,时间复杂度是
下面代码是 wqs 二分。
1 | //2021.8.1 by ljz |
[1011 Segment Tree with Pruning]
solution
题面:给出
1 | Node * build ( long long l , long long r ) { |
问节点数。
做法:显然答案只跟长度有关,而每次是长度除以 map
维护也无所谓了。时间复杂度
1 | //2021.8.1 by ljz |
[1012 Tree Planting]
solution
题面:给你
至少一个
和 不能同时成立 和 不能同时成立( 给定) 最终价值为所有
的 的 之积,求所有方案的价值之和。
做法:考场上某人翻错了题目,我先不谈。
首先有一种经典的想法,就是把
另一方面,更容易想到的暴力是令
我们很容易想到数据分治一下,于是复杂度优化成
以上差不多是我考场上的想法,接下来就让我猝不及防了。
如果你什么都不知道,抱着冲一发的心态随手写了个暴力,想着剪枝,于是把无用态即转移不到的状态全部去掉,然后直接交一发,那么就会意外地发现自己竟然过了此题。
这是为什么呢?我们观察每次的状态意味着什么,我们发现每种状态都至少要满足相邻点的颜色不能相同,哪怕是轮廓线那里的状态,也要满足转折点与相邻都不相同,即多一个点的相邻点颜色不同。这是啥?这等价于一条链上相邻点颜色不同,即链的点独立集,有趣的是,
不知道为什么我代码常数特别大,有没有小哥哥能帮我查查错啊/ll
1 | //2021.8.2 by ljz |