2019杭电多校训练营(第一场)

本文深入解析了ACM竞赛中的算法题目,包括动态规划、线性基、最小割、SAM等高级算法的应用与优化,提供了详细的解题思路与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RankSolvedABCDEFGHIJkLM
40/8545/13ØOØOOØØ.Ø.ØOO

O: 当场通过

Ø: 赛后通过

.: 尚未通过

A Blank

upsolved by chelly


chelly’s solution

首先有个很好想的dp: d p [ i ] [ a ] [ b ] [ c ] [ d ] dp[i][a][b][c][d] dp[i][a][b][c][d]表示填了前 i i i个位置, 0 , 1 , 2 , 3 0,1,2,3 0,1,2,3的最后一次出现位置分别位 a , b , c , d a,b,c,d a,b,c,d情况下的方案数,每个限制在右端点处check。但是这样是 O ( n 5 ) O(n^5) O(n5)的。
注意到 i i i一定和 a , b , c , d a,b,c,d a,b,c,d中的某一个数字相同,所以我们可以压缩一维,时间变成 O ( n 4 ) O(n^4) O(n4)
d p [ t ] [ i ] [ j ] [ k ] dp[t][i][j][k] dp[t][i][j][k]表示填了前 t t t个位置,四个数字最后出现的位置从大到小排序依次是 t > i > j > k t>i>j>k t>i>j>k情况下的方案数。
空间可以滚动成 O ( n 3 ) O(n^3) O(n3)

B

solved by chelly


chelly’s solution

容易想到维护前缀线性基。
现在我们已经有了 [ 1 , R ] [1,R] [1,R]的线性基,如何求 [ L , R ] [L,R] [L,R]的答案呢?
我们可以对线性基的每一个主元位都记录一个最靠右的位置,表示它由这个位置贡献,处理询问的时候,若当前主元位对应的向量最靠右出现位置在 L L L的左边,那么就不考虑这个主元位向量。
插入x的时候,若当前主元位已经有了向量,那就更新成下标最靠右的即可。

C

upsolved by chelly


chelly’s solution

对于每行预处理出 c o s t [ i ] [ 0 / 1 ] cost[i][0/1] cost[i][0/1]表示从中间位置出发,喝 i i i个牛奶,是/否回到中间位置情况下的最小花费。
然后从上往下遍历每行,枚举每行喝多少牛奶,做个背包即可。
如何预处理这个 c o s t [ i ] [ 0 / 1 ] cost[i][0/1] cost[i][0/1]呢?
我们可以以 m i d mid mid为分界线,向左去做个背包,向右去做个背包,然后把两部分 m e r g e merge merge起来即可。
时间复杂度 O ( k l o g k + k 2 ) O(klogk+k^2) O(klogk+k2)

D

solved by viscaria&Feynman1999


viscaria’s solution

E

solved by chelly


chelly’s solution

选出所有最短路径图中的边,对这个图求个最小割就行了。

F

upsolved by chelly


chelly’s solution

容易想到一个dp, d p [ i ] dp[i] dp[i]表示打出前i位的最小花费,那么显然 d p [ i ] = m i n ( d p [ i − 1 ] + p , d p [ j ] + q ) dp[i]=min(dp[i-1]+p,dp[j]+q) dp[i]=min(dp[i1]+p,dp[j]+q)其中要求 s [ j + 1.. i ] s[j+1..i] s[j+1..i]要是 s [ 0.. j ] s[0..j] s[0..j]的子串。
容易发现 d p [ i ] dp[i] dp[i]是单调不减的,所以这个 j j j一定是满足条件的最小的 j j j
假设对于某个局面,我们将 s [ 0.. j ] s[0..j] s[0..j]加入了SAM, s [ j + 1.. i ] s[j+1..i] s[j+1..i]在SAM上走到了某个节点 n o w now now(这意味着它是一个子串),考虑加入 s [ i + 1 ] s[i+1] s[i+1]

  • s [ j + 1.. i + 1 ] s[j+1..i+1] s[j+1..i+1]也能在树上走出,那么就OK
  • s [ j + 1.. i + 1 ] s[j+1..i+1] s[j+1..i+1]不能在树上走出,那么 j + = 1 j+=1 j+=1,将 s [ j ] s[j] s[j]加入SAM,同时 n o w now now要根据当前节点的 m i n l e n , m a x l e n minlen,maxlen minlen,maxlen以及是否有 s [ i ] s[i] s[i]的出边适当在SAM上跳slink链

于是对于每个i,我们都知道了其对应的最小的 j j j,和第一种转移选个最小值即可

G

upsolved by chelly


chelly’s solution

我们的目标是二分一个分数 p q \frac{p}{q} qp,使得不超过 p q \frac{p}{q} qp的答案个数是 k k k,然后通过枚举分母或者在Stern-Brocot树上二分得到最后的答案。
怎么二分这个分数呢?

  • 我们可以手写分数类去二分,那么要二分多少次呢?容易发现精度是 1 n ∗ n \frac{1}{n*n} nn1的,所以我们二分 l o g 2 n log^2n log2n次就行了。
  • 我们也可以固定分母,去二分分子,即二分 x 2 n 2 \frac{x}{2n^2} 2n2x中的 x x x

至于判定就转换成了这样一个问题:求分子分母不超过 n n n的且分数值不超过 p q \frac{p}{q} qp的最简真分数的个数。这个是个经典问题,可以莫比乌斯反演+类欧几里得解决。

最后我们需要找到一个最大的在 p q \frac{p}{q} qp内的解,可以枚举分母或者在Stern-Brocot树上二分得到最后的答案。

H

unsolved


I

upsolved by chelly


chelly’s solution

求字典序最小,就贪心放,维护每个位置的后缀每个字符个数,来判定当前能不能放。

J

unsolved


K Function

upsolved by Feynman1999


Feynman1999’s solution

m = ⌊ n 3 ⌋ − 1 m=\lfloor \sqrt[3]{n} \rfloor-1 m=3n 1

∑ i = 1 n g c d ( f l o o r ( i 3 ) , i ) = ∑ i = 1 m ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) + ∑ i = ( m + 1 ) 3 n g c d ( m + 1 , i ) \sum_{i=1}^{n}gcd(floor(\sqrt[3]{i}),i) = \sum_{i=1}^{m}\sum\limits_{j=i^{3}}^{(i+1)^{3}-1}gcd(i,j) \quad + \quad \sum\limits_{i=(m+1)^{3}}^{n}gcd(m+1,i) i=1ngcd(floor(3i ),i)=i=1mj=i3(i+1)31gcd(i,j)+i=(m+1)3ngcd(m+1,i)

考虑一个函数(前缀和,差分后即为上面部分所求,这个想法也比较自然), f ( n ) = ∑ i = 1 n g c d ( m , i ) f(n) = \sum_{i=1}^ngcd(m,i) f(n)=i=1ngcd(m,i)
f ( n ) = ∑ i = 1 n g c d ( m , i ) = ∑ i = 1 n ∑ d ∣ g c d ( m , i ) ϕ ( d ) = ∑ d ∣ m ϕ ( d ) ∗ ⌊ n d ⌋ f(n) = \sum_{i=1}^ngcd(m,i) \\ = \sum_{i=1}^n \sum_{d|gcd(m,i)}\phi(d) \\ = \sum_{d|m} \phi(d)*\left \lfloor \frac{n}{d} \right \rfloor f(n)=i=1ngcd(m,i)=i=1ndgcd(m,i)ϕ(d)=dmϕ(d)dn
则 注意, m = ⌊ n 3 ⌋ − 1 m=\lfloor \sqrt[3]{n} \rfloor-1 m=3n 1
∑ i = 1 n g c d ( f l o o r ( i 3 ) , i ) = ∑ i = 1 m ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) + ∑ i = ( m + 1 ) 3 n g c d ( m + 1 , i ) = ∑ i = 1 m ∑ d ∣ i ϕ ( d ) ∗ [ ⌊ ( i + 1 ) 3 − 1 d ⌋ − ⌊ i 3 − 1 d ⌋ ] + ∑ d ∣ m + 1 ϕ ( d ) ∗ [ ⌊ n d ⌋ − ⌊ ( m + 1 ) 3 − 1 d ⌋ ] = ∑ d = 1 m ϕ ( d ) ∗ ∑ i = 1 ⌊ m / d ⌋ [ ⌊ ( i d + 1 ) 3 − 1 d ⌋ − ⌊ ( i d ) 3 − 1 d ⌋ ] + ∑ d ∣ m + 1 ϕ ( d ) ∗ [ ⌊ n d ⌋ − ⌊ ( m + 1 ) 3 − 1 d ⌋ ] = ∑ d = 1 m ϕ ( d ) ∗ ∑ i = 1 ⌊ m / d ⌋ [ 3 d i 2 + 3 i + 1 ( 注 意 这 里 是 下 取 整 ) ] + ∑ d ∣ m + 1 ϕ ( d ) ∗ [ ⌊ n d ⌋ − ⌊ ( m + 1 ) 3 − 1 d ⌋ ] \sum_{i=1}^{n}gcd(floor(\sqrt[3]{i}),i) = \sum_{i=1}^{m}\sum\limits_{j=i^{3}}^{(i+1)^{3}-1}gcd(i,j) \quad + \quad \sum\limits_{i=(m+1)^{3}}^{n}gcd(m+1,i) \\ = \sum_{i=1}^{m}\sum_{d|i}\phi(d)*\left [ \left \lfloor \frac{(i+1)^3 -1}{d} \right \rfloor - \left \lfloor \frac{i^3-1}{d} \right \rfloor \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] \\ = \sum_{d=1}^{m}\phi(d)*\sum_{i=1}^{ \lfloor m/d \rfloor}\left [ \left \lfloor \frac{(id+1)^3 -1}{d} \right \rfloor - \left \lfloor \frac{(id)^3-1}{d} \right \rfloor \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] \\ = \sum_{d=1}^{m}\phi(d)*\sum_{i=1}^{ \lfloor m/d \rfloor}\left [ 3di^2 + 3i + 1(注意这里是下取整) \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] i=1ngcd(floor(3i ),i)=i=1mj=i3(i+1)31gcd(i,j)+i=(m+1)3ngcd(m+1,i)=i=1mdiϕ(d)[d(i+1)31di31]+dm+1ϕ(d)[dnd(m+1)31]=d=1mϕ(d)i=1m/d[d(id+1)31d(id)31]+dm+1ϕ(d)[dnd(m+1)31]=d=1mϕ(d)i=1m/d[3di2+3i+1()]+dm+1ϕ(d)[dnd(m+1)31]
因此可以计算 ,时间复杂度 O ( 1 e 7 + T ∗ ( 1 e 7 + 1 e 7 ) O(1e7 + T*(1e7+\sqrt{1e7}) O(1e7+T(1e7+1e7 ) 其中 T T T为数据组数,最左边的 1 e 7 1e7 1e7为预处理欧拉函数的时间。

本题的关键在于推导的倒数第二行变换贡献,从枚举 i i i变为枚举 d d d,使得复杂度降了下来


upsolved by chelly

chelly’s solution

注意到对于上述式子的第一部分,是完整的,所以可以分块打表,然后对于每个询问暴力询问。

L

solved by chelly


chelly’s solution

容易发现交换操作顺序是不影响最后的结果,所以就可以三个NTT。注意求一个多项式卷多次不能直接把点值快速幂,只能分治+NTT求。

M

solved by viscaria&Feynman1999


viscaria’s solution

Dirty Replay

  • E题有个int忘记开成ll,WA了一发
  • L题错误的认为多项式的幂就直接给点值快速幂就行了,实际上需要类似快速幂的分治
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值