ioi赛制好评QAQ

好像啥都记不得了就不写游记了

Day 1

1.1 生成树计数(tree.cpp)

1.1.1. 题意

​ 有 n30000 个点,第 i 个点有点权 ai ,设第 i 个点的点度为 di ,那么求求所有生成树的权值和。一个生成树的权值 w(T) 定义为:

i=1ndimaidii=1ndim
,其中 m30

1.1.2. 题解

​ 原题要求的即为 (n2)!i=1n(di1)!i=1ndi=2n2i=1ndimaidii=1ndim ,考虑若没有最后的 怎么做,类似 m=1 时拆系数的做法,将 dim 拆成下降幂的形式,再将 di2m 拆成下降幂的形式,最后分治 FFT ,时间复杂度 O(nmlog2nm)

​ 可以考虑用多项式 exp 优化,拆成下降幂后的函数为 F(x) 那么实际上就是一些 F(aix) 乘起来,可以多项式 ln 后全部加起来,问题转化为对于 k[0,n]i=1naik ,可以使用分治 FFT 先求出 ek=i1<i2<...<ikp=1kaip ,那么令 fk=i=1naik ,可以发现 i=0xeifxi(1)i=xex(1)x ,可以使用分治 FFT 求得所有 f ,或是直接多项式除法,理解这个式子可以使用容斥。

​ 快速求斯特林数,时间复杂度 O(nlog2n+mlogm)

1.2 无限之环(infinityloop.cpp)

1.2.1 题意

​ 有一个 nm2000 的网格上有水管,四个方向都可能有水管。现在要旋转一些非直线型水管,使得没有水管会漏水。

1.2.2. 题解

​ 利用流量平衡,黑白染色后只要考虑如何连边即可。有困难的地方就是两个方向和三个方向。两个方向只要拆分成横纵分别连边即可,三个方向只要解方程即可。由于必须满流,可以预先加上费用。使用 Johnson 算法可以做到时间复杂度 O(n2m2lognm)

1.3 Hello, world!(helloworld.cpp)

1.3.1 题意

​ 有一棵 n50000 个节点的树,有 Q400000 次操作。要维护在一条路径跳跃,每次跳 k 步,并查询所有路径上点的点权和,或是将这些点的点权和开方。点权和范围 a1013

1.3.2. 题解

​ 显然,最多会有 O(nlogloga) 次有效的开方操作。设块大小为 S ,建立 S 棵树,第 i 棵树上 u 的父亲为原树上的 i 次祖先。树状数组维护路径和,对于修改操作,若 kS 则使用并查集优化暴力更改,否则暴力跳,可以使用树链剖分来跳跃。对于查询操作,直接查询即可。

​ 时间复杂度为 O(nQlognlogloga+Qlogn)

Day 2

2.1 小Y和地铁(metro.cpp)

2.1.1 题意

T=100 组数据,每组数据给定一条线路上的 n44 个换乘站,保证同一条线路最多与当前路径有两个换乘站,且不允许存在三线共点。求最少换乘站总数。

2.1.2 题解

​ 从划分区域角度考虑,只有四种本质不同的划分方案。而若是从左到右,则每次均有两条线路贡献相同。这样暴力,时间复杂度 O(Tn2n)

2.2 小Y和二叉树(binary.cpp)

2.2.1 题意

​ 给定 n106 个点的树上连边,求最小中序遍历。

2.2.2 题解

​ 将中序遍历首位提到根,就可以方便地求出 lcp 和比较。时间复杂度 O(n)

2.3 小Y和恐怖的奴隶主(patron.cpp)

2.3.1 题意

D=166dpT500 次询问第 n1018 项。

2.3.2 题解

​ 向量乘矩阵维护即可。时间复杂度 O(D3logn+TD2logn)

Day 3

3.1 简单数据结构(dsa.cpp)

3.1.1 题意

​ 维护一个支持两端插入删除的队列,操作次数 q105 ,每次操作后求最长的满足后一个数是前一个数的倍数的子序列数目和有多少个位置可以作为这样的长度最长的子序列的开头。保证权值范围 m106 ,每个数字最多被插入 10 次,同一时刻队列中没有相同的元素。

3.1.2 题解

​ 后端插入时暴力枚举约数的约数修改,前端插入时枚举倍数即可,删除是类似的。对于每个位置开一个桶表示后继的长度为 d 的个数即可。

3.2 福若格斯(frogs.cpp)

3.2.1 题意

​ 给一个有限状态(23种)非对称组合游戏,给定 T100m108 个棋盘,每次询问 L 必胜,R 必胜,先手必胜,后手必胜的方案数分别是多少。

3.2.2 转移图与状态对应的 surreal number

清华集训2017题解

3.2.3 分析与解

​ 由图,我们只要分别考虑 >0=0<0 的情况,并求出对应的方案数即可。只要能求出方案数,剩下来的部分只要分别讨论 star 的奇偶性和 updown 的存在情况即可。

​ 显然本质不同的只有 1,12,0,12,1,,, 八种,其中 0 可以忽略不计,后三种也可以单独考虑,因为与 无关。

​ 假设左边有 n 个物品而右边有 m 个,使得左边比右边多选 d 个物品的方案数容易转化为 \mathchoice((((n+mm+d\mathchoice)))) ,只要枚举 11 多几个再前缀和即可。

​ 得到 =0 的个数之后,就没有什么难度了。总的时间复杂度 O(m)

3.3 避难所(hafen.cpp)

3.3.1 题意

​ 构造在 b105 进制下的数位的乘积 n1018 ,并给出一组解证明从 b1 开始试除的贪心是错误的。

3.3.2 题解

​ 一定存在 i  j  j 型解,较大时存在 i  i  i 型解,暴力即可。

Day 4

4.1 我的生命已如风中残烛(game.cpp)

4.1.1 题意

​ 有 T10 组数据,每组数据给定 n500 个钉子,给定 m500 组询问,每次给定长度 L109 和圆心坐标以及初始方向,钉子会对绳子运动造成影响成为新的圆心,问一共要切换几次圆心。

4.1.2 题解

​ 考虑暴力,每次暴力 O(n) 寻找后继,遇到环的时候直接判掉(相当于fmod),由于环最多只会切换 logL 次,时间复杂度为 O(Tn2mlogL)

​ 可以使用主席树解决二维偏序问题,时间复杂度为 O(TnmlognlogL) 。但我们有一个更好的做法,即首先预处理对每个点 u 来说,若长度为 ,从每个 v 过来的绳子会到达哪里,然后每次暴力转即可。由于环是一个凸包,因此每个点只会在每个环上导致转一次。时间复杂度为 O(T(n2logn+nmlogL))

4.2 榕树之心(core.cpp)

4.2.1 题意

T20 组数据,给定一棵 n105 个节点的树,一开始只有 1 节点,而心也在 1 节点。每次可以长一个节点,心也向这个方向移动一格。求心最终可能停留在哪些点。

4.2.2 题解

​ 首先奇偶性不对的点可以直接扔掉,如果点 u 的奇偶性是对的而最大的孩子没有达到 ndepu2dep1=0 那么显然可以构造一组完美匹配来达到解。

​ 因此考虑 dp ,注意到进入一个子树并访问完其中的所有节点后出来的深度是一段连续的区间,且最大值已知,因此令 fi 表示心进入子树并访问完其中所有的点后的最大到节点 i 的距离,gi 表示从 1 走到 i 并访问完上面所有点后到 i 的最小距离,那么对于一个点只要考虑从 1 直接走到 i 后最大的那个子树,如果子树的大小不足的话直接可以满足条件,否则只要用其他的子树来消最大的子树,求出 g 后对应判断一下即可。时间复杂度 O(Tn)

​ 其实可以直接将 1u 路径上的其他部分当成子树,好写好调,被打爆了。

4.3 某位歌姬的故事 (rmq.cpp)

4.2.1 题意

T20 组数据,每组数据询问长度为 n109,且值域为 A109 ,满足 Q500 组形如“序列 liri 位置的最大值为 wi”的限制的序列的个数,取模输出。

4.2.2 题解

​ 对每个位置求出其允许范围内的最大值保证不超过上界,那么一个区间内有值取到 wi 可以转化为在一些上界为 wi 的点上至少有一个取到上界。于是不同的上界可以分开 dp

​ 时间复杂度 O(TQ2)


好像几天的排名单调递增,似乎有点凉凉,WC再见。

相关文章: