IOI2023游记

· · 个人记录

这是整活

这是场内测IOI,本来不让泄露信息的,但是不让我写我就爆破CCF

赛前

居然意外面基到NOI_AK_dreeeam,现实比照片还要珂爱,我问了一下好家伙AK各场NOIIOI省选等各种CCF活动,在CCF组织内比主席地位还要高,%%%%

赛时

T1

分析一波

Test 1

没有退回去的循环,选择跳转数也很少,直接暴力做就行。

Test 2&3

第 2 个点的选择跳转数也不多,同样可以暴力,但第 3 个点就不一样了,所以我们考虑能不能优化。

观察第 3 个点的结构,发现整个事件序列可以划分成若干段,每段又可以分成积累贡献(修改变量 3~12 的值)和统计贡献(根据变量 3~12 各自的值修改变量 1,同时清空变量 3~12)两部分。

显然各段之间的贡献互不影响,同时每段各自的选择跳转数又比较小,所以拆开来分别暴力处理即可。

(这里还有个比较口胡的做法:观察统计过程的部分,实际上就是对所有的变量 3~12,给变量 1 加上其的绝对值。所以我们可以枚举这些变量在统计贡献部分时的正负情况,这样对于积累贡献部分的所有事件,其对于最后变量 1 的贡献就是确定的,直接贪心即可。这样不需要考虑选择跳转数的大小)

Test 4

观察数据,发现整个事件序列很整齐,可以每 6 个分为一组(除去第 1 个事件)。

观察每组事件,发现一组事件相当于一个有大小和价值的物品。也就是说这个点相当于一个 01 背包问题。而第 1 步相当于设置背包的容量。

直接背包问题求方案即可。注意输出时如果当前背包容量塞不下这个物品,那么需要跳过不输出这个物品的选择。

Test 5&6

一上来看第 5 个点容易看错,以为和第 4 个一样也是个普通的背包,然后你会发现提交的返回结果连格式都不对。

认真观察一遍,容易发现第一组事件的跳转位置是最末尾,而且原来第一组事件的最后一个事件语句不见了。而如果翻到数据点最下面,可以发现这最后一个事件出现在最后。

分析一下此时跳转位置的意义,可以发现如果这个物品没有被选上,可能会导致其他一连串的物品也无法被选取。不妨猜测这时的问题从 01 背包变成树形背包。

把一组事件的前 5 个事件看成一个左括号,最后 1 个看成右括号,根据嵌套关系建立出树,做树形背包即可。第 6 个点同理。

因为是提答,所以并不需要很优秀的复杂度,可以直接写 O(nm^2)n 为物品数,m 为背包大小)的做法。实测这种做法在我的电脑上跑第 6 个点只用 3min。

Test 7&8

容易发现其实就是第 2 个点和第 4 个点的缝合,先用 2 的方法计算物品的价值再进行背包。

把两份代码合并一下即可。

(闲话:其实第 1 个点也可以看成这种结构)

Test 9&10

我甚至完全可以猜到这个点想让我干什么。

显然就是把背包换成树形的,所以直接合并第 2 个点和第 5&6 个点的代码即可。

全部代码。

我在分析的时候看了一下NAd,好家伙已经开T3了甚至Devc++都没用直接打代码上交,我黑入CCF测评姬(还是土豆测评姬)发现全部AC,%%%

T2

线段树上维护两个凸包并求连通块,对结果进行三分答案处理后5维DP一遍然后哈希去重

看了看NAd的代码,10行以内解决,%%%%

T3

大模拟,直接模拟就好

T4

system('std4.cpp')直接调用std程序解决

T5

懒得写了,直接套取测评数据交了

赛后

NAd太强了,%%%,在我开T3的时候已经AK了,%%%%%,全程不超5分钟,甚至造了几组数据HACK全部std

后记

参考资料:https://www.luogu.com.cn/blog/Ktian/solution-p1335