连着 4 天没更日记,这下可有的写了。
我们考虑对于 t 扫描线。题目里给定 t 是单调不降的,所以我们甚至不用离线。设我们现在扫描到的 t,当前在处理村庄 u,满足村庄 u 在 t 时刻通车。
我们发现 n 十分的小啊,所以考虑 Floyd。我们处理 u 的时候,拿 u 松弛一下就行了。
其实就是一道 tarjan 强连通板子题。
我们记录 val 表示当前确定的值,k 表示当前确定的位数。
当我们循环到 ai 时,设 x=ai−1−ai+1,我们发现 x 就是它进的位数。于是我们就可以确定在 i−1 处 val 的第 [0,x) 位都是 1 了。于是我们就依次可以确定 val,如果发现 val 已经确定的在 [0,x) 之间的位置不全是 1 就说明不对,无解。
将线段按照左端点排序。设 dpi 表示前 i 条线段所组成的集合的复杂度之和。
考虑如何转移。我们发现:第 i 条线段可选可不选,于是就有一个 2×dpi−1。那么选它对于复杂度的影响呢?它会对所有的 rj<li 的 j 组成的集合都会造成 1 的贡献,设有 x 个 j,那么就会造成 2x 的贡献。
所以我们有 dp 方程:dpi=2×dpi−1+2x,x 可以用桶 + 前缀和预处理,时间复杂度 O(n)。
这道题的 dp 状态设的也是十分神秘啊。
设 dpi,j,k,p 表示循环到了第 i 位,改了 j 个 j,k 个 z,当前这位改过后是 j 还是 z 的最大子串数量。统计答案:ans=maxi=0Kmax{dpn,i,i,0,dpn,i,i,1}。
考虑如何转移。
- 这一位本来是 j
- 不改
那么这一位也不可能和前面组成 jz 子串,所以有 dpi,j,k,0←max(dpi−1,j,k,0,dpi−1,j,k,1)。 - 改
这一位就可以和前面一位组成 jz 子串了,有 dpi,j,k,1←max(dpi−1,j−1,k,0+1,dpi−1,j−1,k,1)。
- 这一位本来是 z
- 不改
同理:dpi,j,k,1←max(dpi−1,j,k,0+1,dpi−1,j,k,1)。 - 改
同理:dpi,j,k,0←max(dpi−1,j,k−1,0,dpi−1,j,k−1,1)。
这题最神秘的地方就在于这个神秘的状态设定。
区间 dp 好题。
设 dpi,j 表示区间 [i,j] 能获得的最大价值。有显然的转移:dpi,j=maxk=ij−1dpi,k+dpk,j。但是对于那写最初并非在一起的区间呢?
我们考虑如何处理这些区间。设 upi,j 表示将 [i,j] 变成一个单调递增的合法区间的最大价值,dni,j 表示将 [i,j] 变成一个单调递减的的区间的最大价值。那么我们有 calc(l,mid,r),表示求 [l,r],峰在 mid 的最大价值:
int calc(int l,int mid,int r)
int len = (a[mid] << 1) - a[l] - a[r] + 1;
if (a[mid] < a[l] || a[mid] < a[r] || len > n)
return up[l][mid] + dn[mid][r] + v[len];
那么我们的转移又要加一个:dpi,j=maxk=ijcalc(i,k,j)。
如何维护 up 和 dn 呢?
- 维护 up
我们发现只有在 ai−1+1=aj+1 的时候,才可以进行转移。所以有:
if (a[i - 1] + 1 == a[j + 1])
for (int l = 1; l < i; l++)
for (int r = j + 1; r <= n; r++)
up[l][r] = max(up[l][r],up[l][i - 1] + up[j + 1][r] + dp[i][j]);
if (a[i - 1] - 1 == a[j + 1])
for (int l = 1; l < i; l++)
for (int r = j + 1; r <= n; r++)
dn[l][r] = max(dn[l][r],dn[l][i - 1] + dn[j + 1][r] + dp[i][j]);
总时间复杂度 O(n3).
唐成啥了。
设 dpi,j,k,p 表示正在处理二进制下的第 i 位,有 j 个数已经确定值了,总共有 k 个 1,要往下进 p 位的权值和。
考虑填表法转移。设要给 x 个数赋 i,那么 j 肯定是变成 j+x 了,k 变成 k+[(x+p)mod2] 了,p 变成 p+⌊2x+p⌋ 了。
那么贡献呢?显然,加上 x 个 i 会在 (xn−j) 中情况里造成 vix 的贡献。所以有转移方程:dpi+1,j+x,k+[(x+p)mod2],p+⌊2x+p⌋←dpi,j,k,p×vix×(xn−j)。
最终的答案呢?我们已经处理完了 m 位,所以正在处理的应当是 m+1 位。而我们填完了 n 个数,要 k+popcount(p)≤K 时就统计进答案,所以有 ans=∑k=0K∑p=0⌊2n⌋[k+popcount(p)≤K]dpm+1,n,k,p。
太唐了不写了。
我们钦定 n≤m(如果不是的话转置一下就是了)。然后枚举 u,d 表示矩阵的上下边界,枚举 i∈[1,m],如果有 mpu,i=mpd,i,我们就把 (u,d,lst,i) 这个矩阵标记出来,并将 lst 置为 i。
然后我们对于第 k∈[1,m] 列进行区间 dp。设 dpi,j 表示能覆盖 x∈[i,j],y=k 的所有点的矩形最小是多大。那么有转移:dpi+1,j=min(dpi+1,j,dpi,j),dpi,j−1=min(dpi,j−1,dpi,j)。但是实现太优秀了调了一上午也没调出来
考完这场模拟赛,这辈子都不会想玩 pjsk 了。
我们发现,题意可以变成这个样子:把 a 分成几个字串,都给替换成它的异或和,得到的数组记为 b,求本质不同的 b 的数量。我们发现,如果定义 ai′=⨁j=1iai,bi′ 同理,那么每个 b′ 都对应一个 b,而 b′ 又一定是 a′ 的字序列,那么就相当于求 a′ 的本质不同的子序列的数量就是了。
神秘数位矩阵 dp。
后日谈
今天给 Frosti 更新了一下。
早上那叫一个颓废,我也不知道为啥这么颓废,多半是因为没做出来 T1 的缘故。
希望明天早上不要这样。
日记
周二 10月 14 2025 1560 字 · 7 分钟