2021.5 省队集训

Day1

A

题目:https://codeforces.com/gym/102978/problem/I

首先,考虑一个序列 (a) 长度为 (m) 的字典序最小的子序列 (x) 有什么性质:

  • (x_1) 一定在 ([1,n-m+1]) 中,且是这个区间内的最小值。
  • (x_2) 一定在 ([2,n-m+2]) 中,因为 (x_1)([1,n-m+1]) 的最小值,所以假如 (x_2)([2,n-m+1]) 中,它一定大于 (x_1)。换句话说,若 (x_2<x_1) 它一定在 (n-m+2) 处。
  • 以此类推。

所以,在 (x) 中只要有一个“拐点”,使得前面单调递增,后面不一定单调递增,那么不一定单调递增的部分就一定是 (a) 的后缀。

所以只需要对前面单调递增的部分进行计数即可。

B

题目:https://codeforces.com/gym/102992/problem/J

我们考虑这个操作 (2)。令 (x=a_loplus a_{l+1}oplus dots oplus a_r oplus x),它需要满足初始局面先手必胜((x eq 0))以及操作一次以后先手必败。如果一个 (i) 满足 (x oplus a_i < a_i),那么可以让这一堆石子剩下 (x oplus a_i) 个。

考虑什么情况下满足 (xoplus a_i<a_i)。可以发现当且仅当 (a_i)(mathbf{highbit}(x)) 上为 (1)

于是需要写一个数据结构,可以:

  • 区间赋值 (max)
  • 区间查询异或和以及在某一位上为 (1) 的个数。

操作 (1) 是 segment tree beats 的经典操作,每个区间记录一个“加”的懒标记即可。

考虑到操作 (1) 的特殊性(每次只会将所有区间最小值增加一个值),每次下传标记的时候撤销原来区间最小值的影响,再计算新值的影响即可。

Day2

A

一种比较蠢的方法是树形 dp。

我们可以发现,对某个非叶子节点执行一次操作,相当于允许它的子树内的某个叶子节点不进行操作。

于是设 (f_i)(i) 所在的子树内的最小代价,(g_i) 为允许一个叶子节点不进行操作的最小代价。

记录每个 (f_i,g_i) 的决策,最后给每个操作随机赋一个值即可。

但这样无法通过,因为随机赋值的值域是 ([1,10^9]),这种范围内随机选值冲突的概率很高(生日悖论)。

我们可以强制让节点的随机值与它的编号有关,这样能提高正确率。

代码:https://paste.ubuntu.com/p/SmbCMvjk22/

B

由于字符串是随机生成的,而哈希也是一种随机的操作,所以哈希值在 ([0,m-1]) 中类似于均匀随机分布。

听 qyc 说比较显然地有 (Theta(n^2))([0,m-1]) 内均匀随机的变量地期望最大值是 (m-dfrac{m}{n^2})

考虑从大到小枚举这个最大的哈希值,设为 (x)。预处理前缀哈希值 (h_i),假如取到这个值的区间是 ([l,r]),那么 (h_r=b^{r-l+1}h_l+x)。整理一下可以得 (b^{-r}(h_r-x)=b^{-l+1}h_{l-1})。把右边插入一个哈希表,但注意要判断是否有 (lle r)

注意哈希表范围要开大一点。假如要哈希的整数的范围是 ([0,N]),哈希表大小为 (M),那么期望一次插入、查询的时间复杂度为 (O(dfrac{N}{M}))

结论:([0,1]) 中均匀随机的 (k) 个实数,其中第 (i) 小的期望是 (dfrac{i}{k+1})

Day3

A

数学题。

字符集大小仅为 (3),根据抽屉原理,单个字符的贡献至少为 (lceil dfrac{n}{3} ceil^2)

设一个循环节长度为 (l) 且循环 (k) 次的子序列是最优的,那么它一定要满足 (k^2lceil dfrac{l}{3} ceil^2<lk^2),解得 (lle 6)

但这样合法的串仍然过多。对于一个子序列,我们枚举它的一个子序列,如果这个更小的子序列产生的贡献比原序列还多,直接舍掉原序列即可。

这样最后只会剩下 (99) 个串,能过。整个序列自动机即可。

B

题目:https://www.cnblogs.com/stoorz/p/14412034.html

发现每种球只要有一个到达点 (1) 即可。

考虑网络流,由于操作有顺序,把每个点拆成 (m) 个,如果第 (i) 次操作 (u,v),那么在第 (i) 层上连边 (uleftrightarrow v),流量限制为 (1)

对于第 ((i-1)) 层的点 (u) 和第 (i) 层的对应点 (u'),连边 (u o u'),流量限制 (a_u)

但这样边的个数达到了 (O(nm)) 级别,其中有许多无用点,把无用的点去掉即可,边数变成了 (O(n+m))

Day6

A

将链转化为环。

增加一个点 ((n+1)),它与点 (1) 和点 (n) 相连,形成一个环。

于是原问题转化为放 (m) 个东西,并可以向左或向右走,在第一个没有标记的地方停下并添加标记,问点 ((n+1)) 没有标记的方案数。

首先让每个机器人随便放,有 ((2n+2)^m) 种方案。

考虑对二元组 ((S,x)) 计数,其中 (S) 表示一种放点的状态,(x) 表示这种状态里未被标记的一个点。

每种状态内一定会有恰好 (m) 个点被标记,有 ((n-m+1)) 个点未被标记。并且,我们只需要知道点 ((n+1)) 没被标记的方案,点都是相同的,于是方案就是 ((2n+2)^m(n-m+1)(n+1)^{-1})

C

题目:https://loj.ac/p/6499

(n,m,sum kle 10^5),考虑用 bitset 搞这个东西。

(V) 是值域,与 (n) 同阶。

对原序列分 (omega) 块,每块存一个大小为 (V) 的 bitset,表示是否出现过这个数。

可以发现 bitset 的或运算满足幂等律,可以用 Sparse Table 存。设 ( ext{st}_{i,j}) 为第 ([i,i+2^j)) 块的 bitset。查询时直接取出来即可,时间复杂度 (O(dfrac{n}{omega}))。预处理的时间复杂度和空间复杂度是 (O(omega log omega imes dfrac{n}{omega})=O(n log omega))

对于零散块,暴力查询,最多有 (O(dfrac{n}{omega})) 个位置,时间复杂度 (O(dfrac{n}{omega}))

Day7

CF516E

势能分析。

(dotsdots)

AGC023E

首先算满足条件的排列个数 (S)。只有 (A_i=n) 的位置可以填 (n)(A_ige n-1) 的位置可以填 (n-1)。于是设 (c_i)(A_kge i)(k) 个数,那么 (S=prod limits_{i=1}^n (c_i-n+i))

假如某个 (c_i) 满足 (c_i-n+i=0),那么 (S=0),特判掉。

现在一种暴力做法就是枚举 (i,j) 满足 (i<j),求出 (P_i>P_j) 的排列 (P) 个数。分类讨论:

  • 假如 (A_i=A_j):个数为 (frac{S}{2})
  • 假如 (A_i<A_j):由于 (P_i) 一定小于等于 (A_i) 所以可以把 (A_j) 变成 (A_i) 并计算合法排列数 (S'),个数即为 (frac{S'}{2})
  • 假如 (A_i>A_j):按照 (A_i<A_j) 的方法做即可。

记前缀积 (f_i=prod limits_{jle i} c_j)(g_i=prodlimits_{jle i}(c_j-1))。那么假如令 (A_jgets A_i),就可以用 (f,g) 表示出 (S')

枚举 (i),用线段树维护。

(dotsdots)

CF555E

先 Tarjan 得出所有 e-DCC,将它们连成有向的强连通分量,这样其中任意两个点之间都连通。并将原图缩成一棵树,假如在这棵树上有 (s o t),那么 (s o operatorname{LCA}(s,t)) 之间的边向上,(operatorname{LCA}(s,t) o t) 之间的边向下。

用树上差分判断是否合法即可。

ARC091F

(SG_k(n)) 表示 (n) 个石子,参数为 (k) 的 SG 函数。

找一下规律,可以发现先手必胜和先手必败是交替的。

(SG_k(n)=egin{cases} dfrac{n}{k} & n mod k=0\ SG_k(n-lfloor dfrac{n}{k} floor)& ext{otherwise} end{cases})

但这样递推可能会 TLE。注意到有时候 (lfloor dfrac{n}{k} floor) 是不变的,这时候直接算出它什么时候会改变或者满足 (nmod k=0)

时间复杂度:

(dots dots)

CF578F

(dotsdots)

AGC035E

对于每个 (x) 满足 (1le xle N),连边 (x o x-2,x o x+k)

然后对于 (k) 的奇偶分类讨论。

(dotsdots)

CF575A

显然 ([f_{i},f_{i+1}]=egin{bmatrix}0 & s_{i-1}\ 1 & s_i end{bmatrix}[f_i-1,f_i])

(A(i,j)=egin{bmatrix}0 & i\ 1 & j end{bmatrix}),答案就是 ([0,1] imes A(s_0,s_1) imesdots imes A(f_{k-1},f_k))

预处理出 (A(s_0,s_1) imesdots imes A(s_{n-2},s_{n-1}))

但这样会有一些特殊点,考虑线段树维护矩阵的乘积。

对于没有特殊点的段矩阵快速幂,有特殊点的乘一下。

用线段树,单点乘,全局查询积。

AGC039E

CF526F

Day8

CF547D

对于一组 (x)(y) 相等的点,我们在它们之间连有向边,剩下的点不管。然后跑二分图染色即可。

为啥它是二分图?

FJOI2013 圆形游戏

先扫描线一遍求出圆之间的包含关系。于是转化成了树上删边游戏。

Day9

A

推一下 (k) 阶等差数列的式子,假如询问是 ([l,r]),那么第 (i) 个位置对答案的贡献就是 (dbinom{r-i+k-1}{k-1})。所以它是一个关于 (r)(k) 次多项式,用树状数组维护每个位置的多项式系数即可。

对于一次单点加操作,实际上是对它所在的树状数组上的区间对应的多项式,每项都乘上 (dfrac{a_i+x}{a_i})

时间复杂度 (O(nklog n))

Written by Alan_Zhao
原文地址:https://www.cnblogs.com/alan-zhao-2007/p/2021-5-SDPTT.html