do_while_true

一言(ヒトコト)

2024.5

pkuwc2024 d2t2 排序

暴力就是按值从大到小填,记录初始序列有哪些位置被填了,每次填上一个数计算它与比它大的数之间的交换次数,模拟一下希尔排序,这个做法是 \(\mathcal{O}(2^nnm)\)

先优化掉状态数,需要 swap 次数最多,那么按 \(d_1\) 分组后每组内部一定是递减的,将已经填入的看成 1,还未填入的看成 -1,当前填进去的数看成 0。首先状态只需要记每一组 -1 的个数,那么状态数到达了 \(\mathcal{O}\left(\left(\frac{n}{d_1}+1\right)^{d_1}\right)\) 级别,可以接受。转移相当于将某个 -1 填成 0,再计算 0 和 1 之间会产生多少次交换,然后再将 0 变成 1 。枚举在哪个位置填并转移是 \(\mathcal{O}(d_1)\)(或者 \(\mathcal{O}(n)\)) 的,问题在于怎样快速计算贡献。

这个时候发现可以记忆化搜索,或者说从 \(d_m\) 往前 dp 到 \(d_1\)。对于每个 \(d_i\) 记录每一组有多少个 -1 以及 0 在哪个位置,分组计算一下逆序对并且组内排序,进行 dp 的转移。这里状态数是 \(\mathcal{O}\left(\sum\limits_{i=1}^m\left(\frac{n}{d_i}+1\right)^{d_i}d_i\right)\) 的(要记 0 在哪一组),单次转移是 \(\mathcal{O}(n)\)。可以通过。

pkuwc2024 d1t2 最小值之和

抄写 skc 的题解,这里 \(a,a'\) 是原题面的 \(f,f'\)

\(dp(l,r,k)\) 表示 \([l,r]\) 中的 \(a'\) 全部减去 \(k\) 是否存在构造,那么 \(dp(l,r,k)\gets dp(l,i,k+j(r-l))\And dp(i+1,r,k+j(r-l))\),也就是在 \(a_i\) 处填 \(j\) 作为最小值,并且让 \([l,r)\) 中的所有 \(a\) 都减去 \(j\) 得以递归处理。

可以将 \([l,r)\) 中的 \(a\) 整体 +1,那么 \(dp(l,r,k)=1\)\(dp(l,r,k-(r-l))=1\),所以另设 \(f(l,r,k)=p\) 为最大的 \(p\equiv k\pmod{(r-l)}\)\(dp(l,r,p)=1\),考虑枚举 \(i\) 之后从 \(f(l,i,w_1)=p_1\)\(f(i+1,r,w_2)=p_2\) 尝试给 \(f(l,r,*)\) 转移。

此时看 \(k+j(r-l)\) 可以为多少,解出 \(\left\{\begin{matrix}x\equiv w_1 \pmod {(i-l)}\\x\equiv w_2 \pmod {(r-i-1)}\end{matrix}\right.\) 并且满足 \(x\leq \min(p_1,p_2)\) 的最大非负整数解 \(x_0\)(这里不用写 exgcd 可以直接暴力),那么它就是能满足 \(x=k+j(r-l)\) 最大的 \(x\),那么所有合法的 \(x=k+j(r-l)\) 通解形式为 \(x=x_0-t\operatorname{lcm}(i-l,r-i-1)\),由于可以令 \(j=0\) 那么最大的 \(k\) 就是 \(x\),所以对每个 \(t\)\(f(l,r,x\bmod (r-l))\gets x\) 更新即可。

注意到只有 \(0\leq t<\frac{r-l}{\gcd(r-l,lcm)}\)\(t\) 是有用的,暴力更新即可。区间 dp 是 \(\mathcal{O}(n^3)\) 的,枚举 \(w_1,w_2\)\(\mathcal{O}(n^2)\) 的,枚举 \(t\)\(\mathcal{O}(n)\) 的,常数极小已经可以通过。

优化就是考虑 dp 的更新形式就是同余最短路,那么将所有 \(f(l,r,x_0\bmod (r-l))\gets x\) 更新好,再将所有 \(lcm\) 拉下来跑同余最短路转两圈。外层枚举区间 \(\mathcal{O}(n^2)\),枚举 lcm 是 \(\mathcal{O}(n^2)\),转两圈更新 dp 是 \(\mathcal{O}(n)\),这样复杂度是 \(\mathcal{O}(n^5)\) 的了。

pkusc2024 d1t3 独立

首先先小 N 的独立集那么做,那么现在问题就是初始 \(f_{x,1\cdots m}=1\),然后树形 dp 合并子树的时候 \(f_{x,i}f_{v,j}\to f'_{x,\max(0,i-j)}\),是个差卷积,能看出来 \(f_{x,i}\) 除了 \(i=0\) 以外的地方是关于 \(i\)\(siz_x-1\) 次多项式,每个 \(x\) 对答案的贡献就是 \(\sum_i f_{x,i}\cdot i\cdot m^{n-siz_x}\)

欲求的 \(f_{x,i}\cdot i\) 前缀和是 \(siz_x+1\) 次多项式,所以尝试直接维护 \(n+2\) 个点值,想插值但是 \(1\sim n+2\) 项会和很多项有关,那么考虑求出倒数 \(n+2\) 项,也就是 \(m-n-1\sim m\) 项的系数,这里可以直接 \(\mathcal{O}(n\log n)\) 算一下差卷积,然后要将这些系数位移到 \(1\sim n+2\),就是 P5667 拉格朗日插值2 这个题。

这里的技巧是尝试写卷积式子之后,想求第 \(x\) 项,但是其中一边的上界是 \(n\) 而不是 \(x\),那么可以将另一边系数整体向右位移 \(n\) 项,这样卷出来的 \(n+x\) 项系数就是我们想要的。

\(m\leq n+2\) 的时候不用平移啥的之类的操作需要特判,直接差卷积合并 dp 就行。那么总的时间复杂度就是 \(\mathcal{O}(n^2\log n)\)

QOJ1288 Tokens on the Tree

【数据删除】


Petrozavodsk Summer 2022. Day 7. HSE Koresha Contest

B 线段树;C 堆模拟;F 贪心选(长度,位置)尽可能小的 \(m\) 个构造。

K. Decoding The Message

什么玩意?抄写摇奖题解...

CRT,\(65535=3*5*17*257\)\(256\)\(3,5,17\) 的值均为 \(1\),模 \(257\) 的值为 \(-1\)。所以模 \(3,5,17\) 下,各个方案的权值就是数位和,否则是偶数位减奇数位的和(0-index)。

假如确定了奇/偶数位的集合,那么答案就会乘上权值的 \(\lceil\frac{n}{2}\rceil!\lfloor\frac{n}{2}\rfloor!\)。其中 \(n\geq 12\) 时其值为 \(\varphi(257)=256\) 的倍数,那么 \(n\leq 11\) 时暴力,否则答案只能是 0 或者 1,取决于权值是否为 \(0\)

现在就只需要考虑判断能否分成模 \(257\) 权值相等的两部分。

对于素数 \(p\)\(p-1\) 个非零数的所有子集和能够表示出整个模 \(n\) 剩余系。

考虑每次加入一个数 \(x\),所有 \(i\to i+x\) 连成了一个长度为 \(p\) 的环,如果当前点已经染黑(可以被表示出来)会使得下一个点染黑,所以如果还有点未被染黑那么一次操作至少会染黑一个点。

那么如果可以挑选出 \(256\)\((x,y)\) 满足 \(x\neq y\) 则可以划分,答案为 \(0\)。否则有 \(n<512\) 或者 \(n-\max\{cnt\}<256\),这两种情况 bitset 暴力即可。

J. Fast Bridges

【数据删除】

I. Best Sun

枚举凸包中最低的那个点 \(o\) + 二分答案。

check 就是 dp,凸包形态相关的 dp 就是按极角序加边,记录当前最后一个点是什么。

首先是对多个起点都要二分答案这个事情,可以先对所有点随机打乱,遍历到一个新的起点之后先看它是否能满足当前的答案,不能的话这个点一定不会是起点,这样的话只有前缀最大值(也就是从后往前的单调栈)会进行二分答案,这样的话只需要 \(\mathcal{O}(n+\log n\log V)\) 次 check。

对于起点 \(o\),能够在凸包上的边 \((i,j)\) 必须满足 \(\triangle oij\) 内部没有其它点,令 \(pos_i\) 为以 \(o\) 为原点 \(i\) 的极角序排名,那么相当于不存在 \(ij\) 左侧有 \(k\) 满足 \(pos_i<pos_k<pos_j\)。考虑固定 \(i\)\(i\) 为原点按照极角序从 \(o\) 逆时针扫,只有 \(pos\) 的前缀最小值才能是合法的 \(j\)。这部分做到了 \(\mathcal{O}(n^2)\)

然后是对于每条边 \(i\to j\) 计算贡献,对于在 \(i\to j\) 右侧且投影在 \(i\to j\) 上的点贡献就是到 \(i,j\) 的距离较小值。问题在于剩下的部分,也就是对于每个 \(x\to y\to z\)\(y\) 右侧有个扇形的区域,它们需要连到 \(y\),做一下差分,大概相当于《极角序小于 \(x\to y\)\(y\) 点处的垂线的点》减去《极角序小于 \(y\to z\)\(y\) 点处的垂线点》,这样就能将贡献拆到每一条边上了。当然这只是一个毛估估的想法,具体实现还有很多细节()总之这部分也能做到 \(\mathcal{O}(n^2)\)

于是总的复杂度就是 \(\mathcal{O}(n^3+n^2\log n\log A)\)


CF983D Arkady and Rectangles

从左到右扫描线,线段树套 set,在一个矩形左边界时区间 push,右边界时区间 pop,每往右扫一次就将能看到但还没标记过的标记为合法。相当于对于某个节点的最大值而言,其要 \(\geq\) 所有祖先 set 最大值,还要 \(\geq\) 子数中所有到叶子的 set 最大值的 \(\min\)

线段树维护还没标记的满足那个条件的值的 \(\max\) 就行。

CF1666K Kingdom Partition

这么你哦,学习一下 F1aMiR3 的理解方式。

最小割模型相当于对每个点有个变量 \(x_u\) 可取 \(0\)\(1\),最小化 \(\sum\limits_{(u,v,w)}wx_u(1-x_v)\),其中 \(w>0\)\(x_S=1,x_T=0\)

对于这个题肯定设 \(x_A\) 表示 \(x\) 是否在 \(A\)\(x_B\) 表示 \(x\) 是否在 \(B\),那么 \((1-x_A-x_B)\) 为 1 则 \(x\)\(C\)。问题在于 \(x_A=x_B=1\) 时后面的值是 -1,它带来的贡献相当于《它是 A 带来的贡献》+《它是 B 带来的贡献》-《它是 C 带来的贡献》。将这种状态称作 D,这时候来看 D 和其它种类的贡献是什么:

  • D 与 A:\(2w+0-w=w\) (1)
  • D 与 B:\(0+2w-w=w\) (2)
  • D 与 C:\(w+w-0=2w\) (3)
  • D 与 D:\((1)+(2)-(3)=0\)

此时发现把 D 换成 C 一定不会更劣,所以跑出来最小割如果是 \(x_A=x_B=1\) 说明 C 和 D 一样优但是最小割选择了 D,将其视为 C 即可,此时再考虑最小割建图的边应该怎么连,对于两个城镇 \(x,y\) 而言,它们之间的代价是:

\[2wx_Ay_A+2wx_By_b\\ +wx_A(1-y_A-y_B)\\ +wx_B(1-y_A-y_B)\\ +wy_A(1-x_A-x_B)\\ +wy_B(1-x_A-x_B)\\ \]

(对着想要的形式)很容易化出来:

\[wx_A(1-y_B)\\ +wx_B(1-y_A)\\ +wy_A(1-x_B)\\ +wy_B(1-x_A)\\ \]

按照这个连边即可,而强制选就相当于强制它与源点连通,与汇点连通,连 inf 边就行。

CF1025G Company Acquisitions

鞅与停时问题,但是我也不懂原理,会列式子就行。

设关于局面的势能函数 \(\varphi\),满足每次操作势能期望 -1,并且末状态势能 \(\varphi_t\) 为常数(不变)且唯一。那么期望步数就是初始势能 \(-\) 末势能。

在这里令 \(f(a)\) 表示有一个激活挂着 \(a\) 个未激活的势能,局面的势能定义为所有 \(f\) 的和。那么列出来 \(f(x)+f(y)-1=\frac{1}{2}(f(x+1)+yf(0))+\frac{1}{2}(f(y+1)+xf(0))\)

\(-1\) 分成两个 \(-\frac{1}{2}\) 并分离变量,相当于要求 \(f(x)-\frac{1}{2}=\frac{1}{2}f(x+1)+\frac{x}{2}f(0)\),注意这一步虽然不是充要的,但是由于我们仅需要找出满足条件的势能函数,所以后面能推出前面即可,这里不知道 \(f(0)\) 也一样,可以直接设 \(f(0)=0\),解得 \(f(x)=1-2^x\)

CF850F Rainbow Balls

还是不写鞅与停时的做法了... 抄的这个理解方式

假设一共有 \(s\) 个球,枚举最后剩下的是哪种颜色,它最开始有 \(a\) 个,其余的就可以看成同种颜色了。那么令 \(f_a\) 表示当前这种球有 \(a\) 个,最终能够统一(为什么不是康师傅而是统一?)的期望步数。\(f_0\) 无定义,\(f_s=0\),令 \(p_i=\frac{i(s-i)}{s(s-1)}\),好像是有 \(f_i=p_if_{i-1}+p_if_{i+1}+(1-2p_i)f_i+1\)\(f_1=p_1f_{2}+(1-2p_1)f_1+1\)

这里问题在于,对于所谓《不能够经过 0 》的处理仅是强制令 \(f_0=0\),而式子中的 \(+1\) 是期望的线性性拆出来当前第一步走的步数是 1。问题在于随机游走的过程中可能到不了 \(s\),而是先到 0 直接死了。

重新审视一下问题,对于 \(i\) 为起点的所有随机路径,如果走到 \(0\) 或者 \(s\) 则停止,但是只有走到 \(s\) 会统计步数,根据期望的线性性,式子中要加的常数实际上是第一次迈出的这一步最终被统计到步数的概率,假定它为 \(g_i\)

那么有 \(g_0=0,g_s=s,g_i=g_{i-1}p_i+g_{i+1}p_i+(1-2p_i)g_i\),稍加化简可以得到 \(g_i=\frac{i}{s}\)。那么正确的式子为 \(f_i=p_if_{i-1}+p_if_{i+1}+(1-2p_i)f_i+\frac{i}{s}\),此时 \(f_0\) 不应参与转移所以可以直接设为 \(f_0=0\)

直接主元法解方程 \(\mathcal{O}(na)\) 复杂度不对。化简出 \(g_i=f_{i+1}-f_i=f_1-\sum_{j\leq i}\frac{s-1}{s-j},g_0=f_1\)。那么 \(f_s=0=sf_1+\sum\limits_{j=1}^{s-1}g_j\),而对于每个 \(\frac{s-1}{s-k}\) 会在 \(j\in [k,s-1]\) 统计到,一共有 \((s-k)\) 个所以贡献是 \((s-1)\),一共有 \((s-1)\) 个这样的 \(k\),所以 \(sf_1=(s-1)^2\),知道 \(f_1\) 之后就能直接递推出所有想要的 \(f_a\) 了,总的时间复杂度是 \(\mathcal{O}(n+a)\)

AGC057E RowCol/ColRow Sort

先考虑值域在 \([0,1]\) 的情况,打表发现 \(A\) RowCol / ColRow Sort 得到的矩阵均为 \(B\),那么满足 \(A\) 中的行之间只有包含关系,不存在相交且不包含,\(A\) 中的列也一样。此时反过来考虑,对于 \(B\) 的每一行映射到 \(A\) 的每一行,再将每一列映射到 \(A\) 的每一列,那就是 \(\{r_i\},\{c_i\}\) 多重集排列的方案数,这里 \(\{r_i\}\) 指的是每行 1 的个数构成的多重集,\(\{c_i\}\) 同理。

套路地,对于 \(k\in [0,8]\),将值 \(\leq k\) 的视作 \(0\)\(>k\) 的视作 \(1\),一个 \(A\) 合法当且仅当形成的这 \(9\) 个 01 矩阵都合法,注意对于每个 \(k\) 的映射 \(p^{k},q^{k}\) 可能是不同的,那么一组映射 \(\{(p^0,q^0),(p^1,q^1),\cdots,(p^8,q^8)\}\) 合法当且仅当对于每个 \(A_{i,j}\leq k\Leftrightarrow B_{p^k_i,q^k_j}\leq k\),一个 \(A\) 可能对应多个这样的排列,只需要计算合法排列组数最后再除以所有 \(k\) 的多重集排列数就行。

现在考虑一组合法排列是什么样子的,相当于一个位置从 0 变成 1 之后不能再变成 0 了,也就是 \(B_{p^k_i,q^k_j}\leq k\Rightarrow B_{p^{k+1}_i,q^{k+1}_j}\leq k+1\),然后这里 \(p^k,q^k\) 具体选取啥只是相当于对 \(B\) 做了一个重排,所以可以直接将其视为单位置换,那么只需要满足 \(B_{i,j}\leq k\Rightarrow B_{p^k_i,q^k_j}\leq k+1\)

对每个 \(k\) 进行一下 dp,假设第 \(i\) 行有 \(a_i\)\(\leq k\),第 \(i\) 列有 \(b_i\)\(\leq k+1\),那么相当于要求 \(j\leq a_i\Rightarrow p_i\leq b_{q[j]}\),也就是 \(p_i\leq b_{q_1},b_{q_2},\cdots ,b[q_{[a_i]}]\)

由于 \(a,b\) 都是越来越小的,那么限制相当于 \(p_i\leq b_{\max\{q_1,q_2,\cdots q_{a[i]}\}}\),那么从后往前确定 \(p_i\),则 \(q\) 会随着 \(a_i\) 增大而逐步确定,这样 DP 第二维仅需要记目前已经确定好了的 \(q\) 的最大值即可,转移可以前缀和优化,总的时间复杂度就是 \(\mathcal{O}(knm)\)

P4770 [NOI2018] 你的名字【口胡】

首先解决如何快速校验一个串是否在文本串的一段区间中出现。

  • 在文本串的 SAM 上线段树合并。
  • 等价于模板串所匹配到的 SAM 节点存在一个 endpos \(p\) 满足 \(p-len+1\geq l,p\leq r\),那么 \(p\) 最大是最优的。对 \(r\) 作扫描线的时候相当于每次插入一个 \(p\),查询子树最大值。如果需要强制在线就可持久化线段树。
  • 将文本串和所有模板串用比 a 小的字符连接起来作 SA,对于一个文本串的询问,相当于问前后 height 不会爆的这个区间里面是否有 \(l\leq sa\leq r-len+1\),找出这个区间需要拿 ST 表倍增,然后询问要可持久化线段树。

考虑这个题,先双指针扫出最大的 \(R_i\) 满足 \([i,R_i]\) 在文本串中出现过,那么答案就是所有 \(T[i,R_i+1],T[i,R_i+2],\cdots,T[i:]\) 去重后的子串个数,仿照本质不同子串计数,按排名从小到达枚举 \(T\) 的后缀计算答案的增量即可。

不想写代码就当它是对的吧/hsh

P8500 [NOI2022] 冒泡排序

A 性质:如果确定了哪些位置填 0 使得限制满足,那么剩余的一定是一个前缀全 0 一个后缀全 1。枚举分界线后前半部分全填 0,后半部分需要从后往前贪心尽可能让 0 少并且往前填。

证明后半部分贪心填 0 是最优的:如果不这么填,一定可以将一个 0 删去或者将一个 0 往前移动,依然满足限制,而且这样操作之后逆序对数一定减少(将 0 删成 1 调整合法是因为这部分在分界线右侧,已经假设好任意填的情况下填 1 比填 0 更优)。

B 性质

已经确立的点之间形成若干段,一个段内首先不能填下降的,调整为从小到大排一定更优,从而这一段中填了某个数和段内其它位置怎么填没有关系了,所以这一段一定只会填一个数。

假如仅考虑点和段之间的贡献,那么每一段的最优选择是非严格递增的,考虑从左往右扫的过程中维护选择某个值 \(v\) 对逆序对的贡献 \(val_v\),每次扫过一个 \(x\)\(val\) 带来的影响是 \(>x\)\(-1\)\(<x\)\(+1\),那么某时刻 \(a<b\)\(val_a\geq val_b\),自此以后 \(val_a\) 再也不可能比 \(val_b\) 更小,那么每一段的最优选择就是非严格递增的。

如果再考虑上段和段之间的贡献,存在《考虑段和段,可以不用非严格递增》\(\geq\)《不考虑考虑段和段,可以不用非严格递增》\(\geq\)《不考虑考虑段和段,需要非严格递增》\(=\)《考虑考虑段和段,需要非严格递增》,所以直接每个段填最优的那个数就是对的!

C 性质

和 B 性质最开始类似,考虑一个限制 \(\min[l,r]=v\),如果内部乱序排成升序一定更优,所以一定有 \(a_l=v\),从而相比于 \(B\) 性质增加了若干限制 \(a[l,r]\) 均要 \(\geq v\)

此时同样考虑从左往右扫,维护 \(val\),初始时所有已经确定 \(v\) 进行 \(>v\) 的 +1,每次扫过一个最初确定的 \(v\) 时进行 \(>v\) 的 -1,\(<v\) 的 +1,如果在某个不确定的位置填上 \(v\),那么只将 \(val\)\(<v\) 的部分 +1。结论是每次选择 \(\geq lim\)\(val\) 最小的 \(v_0\) 就是对的(多个可以任选)。

证明:不会选更大的 \(v\),因为其 \(val\) 更大并且给 \(val\) 带来的影响也更劣;不会选 \([lim,v_0)\) 里的 \(v\),因为 \([lim,v_0)\) 中的 \(val_v<val_{v_0}\),它们再也不会比 \(v_0\) 更优,那么对 \(val\) 的修改都可以统一看为 \(<lim\) 的位置 +1,而既然对 \(val\) 的修改相同,自然选 \(val\) 最小的 \(val_{v_0}\) 更优。

正解

如果确定了哪些位置填哪些数,从而只剩下每个位置有 \(\geq lim\) 的限制需要满足,跑性质 C 的做法即可。

此时考虑所有限制的最大值 \(v\),这些区间一定只能填 \(\geq v\) 的,要确定哪些填 \(v\) 和 A 性质一样贪心即可(证明类似),然后就能将最大值 \(v\) 的这些区间全都删掉,再考虑哪些位置必须填 \(v-1\)

posted @ 2024-05-17 15:40  do_while_true  阅读(27)  评论(0)    收藏  举报