2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解
2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解
update10.01 突然发现叉姐把这场的题传到牛客上了,现在大家可以有地方提交了呢。
不知道该干什么所以就来水一篇题解
题解全是根据印象口胡的,代码是不可能重新写的,这辈子不可能重新写的。
A
description
有一个\(n\times m\)的全\(0\)矩阵,选择一个子矩阵全部修改成\(1\),现在给出修改后的矩阵,问是否存在合法修改方案。
\(1 \le n, m \le 10.\)
solution
找到最左上的\(1\)和最右下的\(1\),判断是否中间全是\(1\),剩下的全是\(0\)就好了。
需要特判没有\(1\)的case。
B
description
给出\(n,k\),求\(\min(\binom{n}{k},10^{18})\)。
\(0 \le k \le n \le 10^9.\)
solution
gzy写的,他一遍过了,反正gzynb就对了。
先令\(k\le \lfloor\frac n2\rfloor\),然后再\(O(k)\)计算组合数,即每次乘一个数再除一个数,可以用long double
或__int128
判断是否超过\(10^{18}\),一旦爆了就直接输出\(10^{18}\)。
C
description
给出一个长度为\(n\)的字符集大小为\(m\)的串,对于\(\forall i\in[1,m]\),求往字符串后面新增一个字符\(i\)后增加了多少本质不同的子串。
\(1 \le n,m \le 10^6.\)
solution
枚举原串的一个后缀,找出这个后缀在串中的其他出现位置,此时可以更新这个位置往后一个字符对应的答案。
实现中可以使用后缀自动机(只要从自动机上原串对应的那个点出发一直跳\(fail\)就行了)或者exkmp(线性求原串与所有前缀的\(lcs\))。
D
description
求有多少长度为\(n\)的序列\(\{a_i\}\)满足:
- \(a_i \in [0,9].\)
- 满足\(m\)条限制,每条限制给出\(l,r\),要求\(\prod_{i=l}^ra_i \equiv 0 \bmod 9.\)
方案数对\(10^9+7\)取模。
\(1 \le n,m \le 50.\)
solution
限制即为要求区间内存在至少两个\(3\)的质因子,在这里可以认为\(0\)包含\(\infty\)个\(3\)质因子。
记\(dp_{i,j,k}\)表示前\(i\)个位置,最近的两个\(3\)质因子在\(j,k\)的方案数,转移是先判掉不合法(对每个限制的右端点维护对应最大左端点),然后在考虑第\(i+1\)位上是填\(\{0,9\}\)还是\(\{3,6\}\)还是\(\{1,2,4,5,7,8\}\)。
E
description
给一个数字串\(S\),要求将\(S\)划分成若干互不相同的\([0,99]\)内的整数,不能含有前导零,求方案数。
\(1 \le |S| \le 50.\)
solution
直接搜。
考虑一位数(包括\(0\))只有\(10\)个,那么确定了一位数的位置后剩下的划分也就随之确定了,假设数字\(i\)出现了\(a_i\)次,那么搜索的总状态数不超过\(\prod_{i=0}^9(a_i+1) \le (\frac{\sum_{i=0}^9(a_i+1)}{10})^{10}=6^{10}\)。
F
description
一个人初始在\((0,0)\),可以走不超过\(n\)步,每一步可以向右走不超过\(a\)步,或者向上走不超过\(b\)步,或者向左走不超过\(c\)步,或者向下走不超过\(d\)步,求这个人可到达的位置数\(\bmod 10^9+7\)。
\(1 \le n,a,b,c,d \le 10^9.\)
solution
等差数列求和直接算就好了。
G
description
有一个\(n\times m\)的矩阵\(\{C_{ij}\}\),需要构造一个\(m\)阶排列\(\sigma\),使得矩阵的所有列向量根据\(\sigma\)重新排列后满足行向量字典序单调不降。要求输出满足条件的字典序最小的
\(1 \le n,m \le 2000.\)
solution
考虑\(n=2\),那么每一列的两个数的大小关系只有以下三种:\(C_{1j}>C_{2j}\)或\(C_{1j}=C_{2j}\)或\(C_{1j}<C_{2j}\)。由于需要满足第二行的字典序大于等于第一行,那么所有\(C_{1j}>C_{2j}\)的\(j\)都需要排在至少一个\(C_{1k}<C_{2k}\)的\(k\)后面。
这个限制可以抽象成:给出\(\{1,2,...,m\}\)的两个子集\(A,B\),满足\(A\cap B = \varnothing\),要求在最终的排列\(\sigma\)中,\(B\)中每个元素都至少排在一个\(A\)中元素的后面。
\(n>2\)的情况就是给出了多组\(A,B\)。
令每个点的入度为包含这个点的\(B\)集合数量,每次选择一个入度为零且编号最小的点(保证字典序最小)放在当前排列末尾,如果这个元素在某些\(A\)集合内是第一次出现,那么就把这个\(A\)对应的\(B\)中所有元素的入度减\(1\)。
总时间复杂度\(O(nm+m\log m)\)。
H
description
一张\(n+m\)个点的图,初始在\(1\)号点,每次在\(i\)号点的时候有\(P_{i,j}\)的概率走到\(j\)号点,保证\(\forall i\in[n+1,n+m],P_{i,j}=[i=j]\)。可以发现经过无限次行走后停留在前\(n\)号点上的概率是\(0\),求停留在后\(m\)号点每个点的概率\(\bmod 10^9+7\)。
\(1 \le n + m \le 500.\)
solution
设\(f_i\)表示经过\(i\)点的期望次数,于是
高斯消元解出\(f_i\)后随便算一下就好了。
I
description
给一棵树,边有边权,求有多少条路径满足边权和是\(2019\)的倍数。
\(1 \le n \le 20000.\)
solution
点分即可。
J
description
给出\(n\)个\(m\)元组\((a_1,a_2,...,a_m)\),记\(count(x)\)表示有多少个\(m\)元组满足\(\forall j\in[1,m],popcount(a_j\land x)\)为奇数。求\(\sum_{x=0}^{2^k-1}count(x)3^x \bmod 10^9+7\)。
\(1 \le n \le 10^4, 1 \le m \le 10, 1 \le k \le 30, 0 \le a_i < 2^k.\)
solution
对于每个\(n\)元组单独求答案然后相加即为答案。
把\(m\)元组写成一个\(k\times m\)的\(01\)矩阵,相当于选出一些行向量做异或运算,要求结果为\(2^m-1\)。直接按二进制位\(dp\),记\(f_{i,j}\)表示处理完前\(i\)位,当前二进制状态为\(j(j\in[0,2^m))\)的方案数。
总复杂度是\(O(nk2^m)\),大概能过的样子。
K
description
维护\(n\)个链表以及\(m\)次操作,每次操作为将一个链表剪切到另外一个的后边并将其翻转。
\(1 \le n,m \le 10^5.\)
solution
直接启发式合并即可。
不过要我写可能就直接上treap了。