SWJTU_LightMoon Training #11
C AC自动机+dp
- 用Trie数出不同前缀的个数sz后,可知可能的串的总数为sz^2。但有重复,比如同个字符串可以有多个断点使得条件成立。
- 多个断点我们统一只统计最长的前缀,其他重复的必然是他的后缀,于是使用AC自动机跳fail。每个节点维护cnt:以这个串为后缀的前缀个数。
- 对fail图拓扑排序,dp维护cnt。
D 面积交裸题,然而我没有一个靠谱的模板,所以没A,有点可惜
[Megumin的代码] (代码什么的,当然是不存在的呀)
F 4 / 29
G 1 / 67 Stern-Brocot树
H 首先,没有高速公路的话,区域是一个圆,如果有高速公路,那么到达高速公路后可以沿着高速公路走一段,再继续往外走,很显然,除去高速公路的一段路,另外两段路应该是平行的,,那么我们可以先求出到高速公路的最优点,然后问题就转化成了圆和两个三角形的面积并,那么用圆的面积加上三角形的面积减去圆和三角形的面积交即可
[Megumin的代码] (代码什么的,当然是不存在的呀)
J 计数DP
- 由于每个点的度数最大为3,我们可以从中间把这棵树切开,那么这棵树便分成了二叉树,当(K)为奇数时,直径最中间的作为分割点,那么可以分成3颗二叉树,如果(K)是偶数,那可以从直径中间分成2颗二叉树,那么,我们只需要计算不同构的二叉树的数目,然后再来考虑计算最后结果。
- 考虑(dp)计算。(dp[i])表示深度为(i)的不同构二叉树数目,(sum[i])表示深度小于等于(i)的不同构二叉树数目之和
- 计算(dp[i])时:
- 两侧的子二叉树深度同时为(i-1),两种情况:1.两者相同:(dp[i-1]);2.两者不相同(dp[i-1]*(dp[i-1])/2)
- 一侧深度为(i-1),另一侧小于(i-1):(dp[i-1]*sum[i-2])
- 然后我们来计算最后结果,分成奇偶两种情况来考虑:
- 容易知道二叉树最大深度为(n=K/2)
- (K)为偶数:此时两颗二叉树深度均为(n),那么结果同上(dp)计算,为(dp[n]*(dp[n]+1)/2)
- (K)为奇数:此时至少有两颗二叉树深度为(n)
- 当另一颗二叉树深度小于(n),结果为(dp[n]*(dp[n]+1)/2*sum[n-1])
- 当另一颗二叉树深度等于(n),有以下三种情况:
- 三颗二叉树均相同:(dp[n])
- 有两颗二叉树相同:(dp[n]*(dp[n]-1))
- 三颗树均不相同:(dp[n]*(dp[n]-1)*(dp[n]-2)/2/3)
Megumin的代码
SWJTU_LightMoon Training #12
B 90 / 835 二分
C 3 / 32 字符串+构造
D 找规律
E 2 / 8
F 99 / 446 DP
- 蚂蚁k如果不在右边界n处,那么为了别去送死,只能向左走。在左边至少要吃掉多少蚂蚁才能存活呢?体重总和大于前面的总和即可。
- 求出左边的走法后,我们用相似的做法求出右边的走法。设dp[i]为蚂蚁k胜利的种数,则dp[i] = sum{dp[k]|tot[k]>=tot[i]-tot[k+1]}。由于k的取值范围必为一段区间,于是可以用pre_dp[]表示dp[]的前缀和快速求解。如果蚂蚁在右边界,要把结果乘以2,因为这时蚂蚁两个方向都可以走。
G 1 / 12
H 2 / 42
I 1 / 6
J 51 / 201
K 1 / 92
L 数学模拟 先按出现数字个数分类,然后枚举第一个数的sqrt去判断就行
SWJTU_LightMoon Training #13
A 3 / 19 高斯消元+bitset
B 1 / 14
C 有上下界的费用流 此问题转化成有源汇的上下界费用流求 S→T 流量为总黑子个数的最小费用。
求解有源汇上下界费用流可转换为求无源汇上下界最小费用可行循环流
建图过程:
1.S向每行(列)连一条有上下界的边,流量上下界为该行(列)黑子个数
2.每一行(列)向T连有上下界的边,流量上下界为Rl、Rh(Cl、Ch)
3.对每对棋子,同色不用考虑,不同色要考虑是否同行同列,同行则表示其交换对对应两列产生影响(对行无影响),从当前 pair 中代表黑子的列向代表白子的列连一条边,流量上下界分别为 0、1 ,单位费用为 1
4.T→S 连边,流量上下界为0、inf
最后,在前几个的基础上(修改),对每一条边 (u, v) ,再新图中添加一条 supS→v 流量为 u、v 流量下界的边。一条 u→supT 流量为 u、v 流量下界的边,一条 u→v 流量为 u、v 流量上界-流量下界的边
WQF的代码
G 1 / 40
H 圆并+二分,就一模板题
[Megumin的代码] (代码什么的,当然是不存在的呀)
I 将和表示成前缀和只差,然后二项式展开,合并之后可以(O(n*k))计算
[Megumin的代码] (代码什么的,当然是不存在的呀)
J 0 / 3
SWJTU_LightMoon Training #14
A 8 / 175 贪心+dfs
C 0 / 5
D 1 / 4 fft
E 虽然知道了这题的做法,但是还是不能AC,大概是个sb错
[Megumin的代码] (代码什么的,当然是不存在的呀)
H dp 所有点的总度数是(2*n-2),每个点的度数范围是(1~n-1),那么,我们只需要给这(n)个点分配(1~n-1)的度数,然后总和是(2*n-2)就能够构成一棵树。可以很容易的想到(O(n^3))的(dp),但是不能通过这题。由于每个点的度数至少为(1),那么,先给每个点分配(1)的度数,这样还剩下(n-2)的度数,此时,剩下的度数可以随意分配,考虑利用完全背包来求解这个问题即可
I 0 / 11
K 0 / 6
M 0 / 7
SWJTU_LightMoon Training #15
B dfs+剪枝 or 黑白相间染色
- dfs+剪枝 由于数据范围很小,可以考虑爆搜+剪枝,很显然,当一种颜色的数目大于剩余格子的一半时,是不可行的。然后搜索可以先填满一行,填满后再填另一行去进行。
Megumin的代码 - 当时训练的时候并没有考虑爆搜,因为想到了黑白相间染色然后填数的方式,应该是明显优于爆搜的方法,可惜有一步没有得到很好的实现