Atcoder 题目选做(二)


By DaiRuiChen007




*1. [ARC145F] Modulo Sum of Increasing Sequences

Problem Link

给定 n,m,p,对于所有 r[0,p) 求有多少长度为 n,值域 [0,m] 的单调不降序列数组在 mod p 意义下的序列和为 r

数据范围:n,m106,p500

先考虑令序列中的 aiai+(i1),此时原序列和一个值域 [0,n+m1] 的单调递增序列构成双射,因此令 mn+m,我们只要考虑值域 [0,m) 的问题。

首先建立二元生成函数,F(x,y)=i=0m1(1+xiy),答案 ansk=[xkyn]F(x,y)mod(xp1)

考虑对第一维进行单位根反演,设 [xi]F(x,y)=fi(y),此时得到:

ansk=[yn]i=0m1[pik]fi(y)=[yn]1pi=0m1fi(y)j=0p1ω(ik)j=[yn]1pj=0p1ωjki=0m1fi(y)ωij=1p[yn]j=0p1ωjkF(ωj,y)

但是 F(x,y) 的形式不够优美,我们想要 pm,因此我们用一个暴力背包处理 [mmmodp,m) 中的元素的选择方案,dpi,j,k 表示前 i 个数选 j 个,mod p=k,复杂度 O(p3)

然后对于 [nmmodp,n] 中的每个 n 求出 n=n 时的答案,再和后半部分的暴力背包合并一下即可。

还是回到原问题,进一步展开 F(ωj,y),记 g=gcd(p,y),展开时用分圆多项式处理:

F(ωj,y)=i=0m1(1+ωijy)=i=0p1(1+ωijy)m/p=i=0p/g1(1+ωgiy)mg/p=i=0p/g1(1+ωp/giy)mg/p=(1(y)p/g)mg/p

最后一步由分圆多项式 i=0n1(zωni)=zn1 稍作变形得到。

带入原式得到:

ansk=[yn]j=0p1ωjk(1(y)p/g)mg/p=[yn]gp(1(y)p/g)mg/pt=0p1[gcd(t,p)=g]ωkt=[yn]gp(1(y)p/g)mg/pt=0p/g1[gcd(t,p/g)=1]ωkgt=[yn]gp(1(y)p/g)mg/php/gμ(h)t=0p/gh1ωkght=[yn]gp(1(y)p/g)mg/php/gμ(h)t=0p/gh1ωp/ghkght=gp[yn](1(y)p/g)mg/php/gμ(h)pgh[p/ghk]=gp[yn](1(y)p/g)mg/php/gμ(h)pgh[pghk]

最后一步根据逆用单位根反演得到。

此时前面的二项式系数可以简单讨论根据组合数算出,对单个 n,k 求出答案的复杂度为 O(d2(p))

时间复杂度 O(n+m+p3+p2d2(p))

Submission Link




2. [AGC018E] Sightseeing Plan

Problem Link

给三个矩形 R1=(x1,y1,x2,y2),R2=(x3.y3,x4,y4),R3=(x5,y5,x6,y6),保证三个矩形左下到右上排列,求有多少种路径 uvw 满足 uR1,vR2,wR3

不同的 u,v,w 或不同的路径均算作不同的方案。

数据范围:x1x2<x3x4<x5x6,y1y2<y3y4<y5y6n=max{xi,yi}106

先考虑点 (0,0) 到矩形 (x1,y1,x2,y2) 的方案,显然前缀和转化成 (0,0)(0,0,x,y) 的方案,容易得到:

Ans=i=0xj=0y(i+ji)=i=0xj=0y(i+j+1i+1)(i+ji+1)=i=0x(i+y+1i+1)=1y!i=0x(i+y+1)y=1y!×1y+1(x+y+2)y+1=(x+y+2x+1)

因此 (0,0)(0,0,x,y) 的方案等价于 (0,0,x+1,y+1) 的方案,那么原问题中 R1vR3 也可以用类似的技巧转成 16svt 的方案数,其中 s,t 是定点,vR2

考虑进入 R2 的的位置 (ix,iy) 和离开 R2 的位置 (ox,oy),容易发现 (ix,iy) 属于下边界上的点构成的点集 D 或左边界上的点构成的点集 L(ox,oy) 属于上边界上的点构成的点集 U 或右边界上的点构成的点集 R

不妨假设 (ix,iy)L,(ox,oy)RF(uv) 表对应路径数,那么得到对应路径的贡献:F(s(ix1,iy))×F((ix,iy)(ox,oy))×F((ox+1,oy)t)×(ox+oyixiy+1)

考虑拆分贡献,分成 F(s(ix1,iy))×F((ix,iy)t)×(ix+iy)F(s(ix1,iy))×F((ix,iy)t),以及 F(s(ox,oy))×F((ox+1,oy)t)×(ox+oy) 三部分,每部分只要 O(n) 枚举 L/R/U/D 的其中一个即可。

时间复杂度 O(n)

Submission Link




*3. [AGC022F] Checkers

Problem Link

给定 n 个数 ui=10100i,每次选定 i,j,使得 ui2ujui,然后删掉 uj,求最终的向量有多少种可能结果。

数据范围:n100

容易发现我们只关心每个数对答案的贡献系数。

考虑在上述过程中把 j 变成 i 的儿子,那么整个过程会形成一棵树,我们认为最后一次操作的 ji 的第一个儿子。

我们只关心每个点对答案的贡献系数,每次操作会把 i 所在连通块系数取反,j 所在连通块系数 ×2

注意到每个点对答案的贡献都是 ±2k,其中 k 只与深度有关,正负号则与当前节点的儿子数以及其在父亲中的排名有关。

定义一个点的原符号为,不考虑这个点的所有儿子时,这个点的符号。

具体来说,如果他是父亲的第 1,3,5,7 个儿子,那么他的原符号与其父亲的原符号相等,否则相反。

最终一个点的符号与其原符号相等当且仅当其儿子数量为奇数。

我们尝试对树的形态进行计数,但这与一个系数组合不构成双射,我们需要对树的形态做出进一步的限制。

对于同一层的两个节点,如果他们有不同的原符号,并且他们都有奇数个儿子,那么把一个儿子移动到另一边不会影响答案,因此我们必须钦定所有有奇数个儿子的点拥有相同的原符号。

考虑最后一层的填法,我们发现该填法有解当且仅当两种符号的差与上一层有奇数个儿子的点的数量一致。

而对于中间的层,我们可以先填原符号,然后把一些点设奇数个儿子来调整符号。

容易发现,根据这样的方式构造树结构,只要最后一层满足条件,任何一组系数都是合法的。

那么我们只要设 f(i,j) 表示已填 i 个节点,最后一层有 j 个点度数为奇数的方案数,设这些点原符号为 s,枚举实际符号与 s 相等和不等的节点数量 x,y

考虑原符号与 s 相等的节点数量,显然这个答案就是 12(x+y+j),因为删掉 j 个奇数点每个点一个儿子,剩下点正负号恰好平分,而被删掉的儿子符号都为 s

因此对于下一层我们需要 |x12(x+y+j)|=12|xyj| 个点取奇数个儿子,因此得到:

f(i+x+y,12|xyj|)f(i,j)(nix+y)(x+yx)

转移条件为 i+x+yn,x+y>0,x+yj,2x+y+j,边界条件为 f1,0=f0,1=n,终止状态为 fn,0

暴力 dp 即可做到 O(n4)

考虑展开组合数,并分离变量得到:

(nixy)!×f(i+x+y,12|xyj|)(ni)!f(i,j)x!y!

转为计算 f(i,j)=(ni)!f(i,j),然后分步转移 x,yf(i,j)x!g(i+x,xj),g(i,j)y!f(i+y,12|jy|)

转移条件为 i+yn,j+y0,2j+y,但 x+y>0 的条件未处理,直接在 fg 一步钦定 x>0x=0 的情况暴力转移即可。

时间复杂度 O(n3)

Submission Link




*4. [ARC146F] Simple Solitaire

Problem Link

定义一个序列 a 的权值 w(a)mex(a) 的元素数量,定义一个排列的权值为 i=1n1w(p[1,i])×[w(p[1,i])<m],对于所有 n 阶排列求权值和。

数据范围:n2×105

一般来说,涉及 mex 的问题都是删除比插入容易,因此考虑倒序 dp。

fi,j 表示 w(p[1,i])=j 时的方案,如果 pimex(p[1,i]),那么删除后 jj1,有 j 种删除方法,否则 jk,其中 kj

因此转移为 fi1,j1fi,j×j2fi1,kfi,j×j(m>kj),最终 dp 为 fn1,1fn1,m1f1,1 的方案数。

考虑组合意义,那么每个 jk 转移分段,相当于原序列变成若干值域连续下降段,且当前段尾不超过下一段段头,权值为段内每个 j 的平方,除以段尾的一个 j,要求序列尾为 1

考虑容斥,钦定若干个连续段值域严格下降,对于 s 个连续下降段,容斥系数为 (1)s1

转到值域上考虑,用 GF 辅助记录连续下降段中元素个数,gv,0/1 表示考虑了 [v+1,m1] 中的元素,其中 v+1 是 / 不是段中非段尾元素,用矩阵 Mv 维护转移:

  • 如果当前元素是空(不在序列中),那么 M0,01
  • 如果当前元素是段尾,那么 M1,0,M0,0vz,容斥系数在这里处理,其中 z 是 GF 记录序列大小的占位符。
  • 如果当前元素不是段中非段尾元素,那么 M0,1,M1,1v2z

分治 NTT 维护 Mm1××M1,得到单段的 GF F,那么所求就是 [zn1]11F

记得系数 ×1,因为我们此时每段都给系数乘了 1,而实际容斥系数应该是 (1)s

由于我们要求序列在 1 结束,因此特殊处理最后一个序列,即只维护到 Mm1××M2,求出钦定 1 必须被选的 GF G,答案是 [zn1]G1F

时间复杂度 O(nlog2n)

Submission Link




*5. [AGC039F] Min Product Sum

Problem Link

对于一个 n×m 的值域 [1,k] 的矩阵 A,定义 xi 表示第 i 行最小值,yj 表示第 j 列最小值。

定义一个矩阵权值为 i=1nj=1mmin(xi,yj),求所有矩阵权值和。

数据范围:n,m,k100

考虑如何刻画矩阵的权值。

假设我们已知 {xi,yj},那么一个矩阵的权值就是有多少个矩阵 B 使得 Bi,jmin(xi,yj)

同理 A 矩阵就要求 Ai,jmax(xi,yj),但是要容斥至少一个 Ai,j=xi,容斥处理某一列 Ai,j>xi 即可。

我们从大到小填每个 xi,yj,插入时处理对应行列的贡献,注意到我们可以分步转移,即每次插入若干个 x/y 相等的正常行或列 或有容斥限制的行或列。

具体来说,我们设 fv,i,j ,表示插入了值域为 [1,v] 的元素,已经填了 ij 列,分步转移如下:

  • 插入 p 个被正常的行:

    fv,i+p,jfv,i,j×(nip)×(vmj×(kv+1)j)p

    即有 j 个列的值 <k,这些交点的 max(xi,yj) 确定可以填 Ai,j,每个 kv+1 种方案,mj 个列的值 k,这些交点的 min(xi,yj) 确定,可以填 Bi,j,每个有 v 种方案。

  • 插入 p 个被容斥的行:

    fv,i+p,jfv,i,j×(nip)×(1)p×(vmj×(kv)j)p

    此时 jmax(xi,yj) 确定的交点因为容斥必须填 >v 的数,方案数 kv,容斥系数 (1)p

  • 插入 p 个正常的列:

    fv,i,j+pfv,i,j×(mjp)×(vni×(kv+1)i)p

    意义同上。

  • 插入 p 个被容斥的列:

    fv,i,j+pfv,i,j×(mjp)×(1)p×(vni×(kv)i)p

    意义同上

根据如上过程分步转移即可,本题轻微卡常,注意实现常数。

时间复杂度 O(knm(n+m))

Submission Link




*6. [ARC147F] Again ABC String

Problem Link

给定 n 求有多少长度为 n 的 012 串 S,设 S[1,i] 中 0/1/2 的数量分别为 ai,bi,ci,那么对于任意 i 都有 aibix,biciy,ciaiz,答案对 2 取模。

数据范围:n,x,y,z109

可以考虑转成三个棋子互相追及的问题,即 0 棋子在在 1 棋子后面 x+1 个位置,1 棋子在 2 棋子后面 y+1 个位置,2 棋子在 0 棋子后面 z+1 个位置,可以看成一个环,环长 m=x+y+z+3

要求就是每次移动一个棋子一步,共移动 n 步,要求任何时候没有棋子重叠。

注意到:当两个棋子重合后,下一步如果移动这两个棋子中的一个,我们可以交换他们的名字,使得无论移动哪个都等价,因此这些情况的总数一定是 2 的倍数,不改变答案奇偶性。

因此我们只考虑最终状态有两个棋子重合,且此前没有重合产生的方案数。

进一步注意到如果一个方案有重合那么必定对答案无贡献,因此我们可以直接去求最终状态有两个棋子重合的方案数,多算的部分是一个偶数,无影响。

但是三个棋子全部重合的情况被多算了,要减掉两倍的这些情况,但由于减去了两倍因此也无贡献。

总方案数是 3n,因此答案就是有两种棋子最终重合的方案数之和最后异或上 1(总方案数)。

而两种棋子重合相当于求 [zk](1+z+z1)nmodzm1,其中 k{x+1,y+1,z+1}

注意到 (1+z+z1)2=1+z2+z2+2(1+z+z1)1+z2+z2(mod2)

因此我们可以对 n 进行二进制分解,设 n=di,其中所有 di 都是 2 的幂,那么答案就是 [zk](1+zd+zd)modzm1

如果 m 较小,可以每次暴力多项式乘法,时间复杂度 O(mlogn)

否则 n/m 较小,我们可以不对 zm1 取模转而求每个 zk+im 的系数:先 ×zn 去掉符号,即求 [zk+im+n](1+zd+z2d)

相当于给定一些 ci,每个可以给 S 的二进制下第 ci/ci+1+1,或者不加,求多少种方案能使得 S=k+im+n,数位 dp 记录上一个进位是多少即可,时间复杂度 O(mnlogn)

直接对 m 根号分治即可。

时间复杂度 O(nlogm)

Submission Link




7. [AGC045F] Division into Multiples

Problem Link

q 组询问,给 X 个数字 aY 个数字 b,求能将这些数字划分成多少组,使得的数字和都是 c 的倍数的组尽可能多。

数据范围:q2×104,a,b,X,Y,C109

首先观察,若 gcd(a,b)=d1,那么可以构造子问题:aa/d,bb/d,clcm(c,d)/d

gcd(a,c)=d1gcd(a,b)=1,那么显然每一个组里 b 的数量都是 d 的倍数,那么可以构造子问题:aa/d,cc/d,YY/d

同理处理 gcd(b,c)1 的情况,最终可以构造一个等价问题使得 a,b,c 两两互质。

q=a×b1modc,那么每一组里 a,b 元素的个数一定形如:(x,x×qmodc)(余数为 0 时取 c)。

显然如果存在 x1<x2 满足 x1×qmodc<x2×qmodc,那么 x2 一定不优,因此所有合法决策随着 x 递增,y 递减。

那么考虑最前面连续的一段:(0,c)(q/c,cmodq),这一段里的元素构成等差数列,然后考虑下一个合法段的 y 坐标:只需要考虑 <c=cmodq 的坐标,由因 qcc,因此我们直接取 q=qmodc 依然能求出所有合法的 y 坐标,我们只要这样递归子问题即可。

容易发现这就是辗转相除法的过程,因此所有合法决策构成的等差数列是 O(logV) 级别的,并且斜率递减,即构成下凸壳。

观察发现我们选定的所有决策一定在下凸壳的同一条边上,否则把两个决策相向调整可以得到两维都更优的解。

因此我们求出每个等差数列,对每个等差数列在上面二分一个阈值 k,设等差数列形如 (x0,y0)(x0+nΔx,y0nΔy)

把所有 Δ 偏移量的和设为 s,合法条件就是:sknkx0+sΔxXky0sΔyY,直接判断即可。

时间复杂度 O(qlog2V)

Submission Link




8. [AGC048D] Pocky Game

Problem Link

给定 n 堆石子,第 i 堆有 ai 个,先手每次可以从第 1 堆取 [1,a1] 个石子,后手每次可以从第 n 堆取 [1,an] 个石子,求谁能取完最后一个石子。

数据范围:n100

观察发现答案具有一定的单调性:如果当前局面先手必胜,那么 a1a1+1 先手还是必胜,只要第一步多取一个即可。

同理后手必胜的局面令 anan+1 后手也必胜。

那么我们可以设 fl,r/gl,r 表示 a[l,r] 作为游戏初态,其中 al/ar 至少要修改成多少才能使得先手 / 后手必胜。

手玩一下策略,如果 (l,r] 后手必败,即 ar<gl+1,r,那么先手可以直接取完 al,即 fl,r=1

否则先手肯定要脱尽可能的时间让后手不断消磨 ar 直到后手不能胜利且自己能胜利。

那么想要后手输掉,需要至少 argl+1,r+1 轮才能让后手必胜,且这个过程内始终要保持自己不能输掉 a[l,r) 的游戏,否则后手直接删空 ar 就能赢,那么答案是 fl,r1gl+1,r+ar+1

gl,r 的计算也类似,区间 dp 一下即可。

时间复杂度 O(n2)

Submission Link




9. [AGC056B] Range Argmax

Problem Link

给定 m[1,n] 的子区间 [l1,r1][lm,rm],对于一个 1n 的排列 p,定义 xi 表示 p[li,ri] 中最大值的下标。

求有多少个可能被生成的 x1xm

数据范围:n300,mn(n1)2

考虑把每组 {xi} 唯一对应的一组 {pi} 上,考虑用插入的方式刻画。

依次插入 n1,每次把对应值插到当前的最左边的可能位置。

设当前最大值插到了 u 上,那么所有包含 u 的区间的 xi 都已经确定了,原问题被分成了 [1,u),(u,n] 两个部分。

但是我们还要限制 u 是第一个可能的取值,那么考虑 [1,u) 中的最大值 v,当且仅当存在一个区间同时包含 u,v

因此我们可以发现如下的子结构并 dp:dpl,r,u 表示 [l,r] 内,最大值的最小取值必须填在 [u,r] 中的方案数。

我们设 pos(L,R,u) 表示所有 u[li,ri][L,R] 的最小 li,那么有如下转移:

dpl,r,u=dpl,r,u+1+dpl,u1,pos(l,r,u)+dpu+1,r,u+1

预处理出 pos 后暴力转移即可。

时间复杂度 O(nm+n3)

Submission Link




10. [ARC149D] Simultaneous Sugoroku

Problem Link

给定一个动点 xm 次操作给定 d:若 x<0xx+dx=0 则停止运动,x>0xxd

n 次询问初始 x=x1xn 时,x 会不会停止,什么时候停止,或最终移动到了哪里。

数据范围:x106,n,m3×105

注意到值域并不大,因此我们可以维护所有 [1,V] 的答案,注意到某个时刻两个动点位置互为相反数,那么他们之后的位置也一定互为相反数。

类似 [Ynoi Easy Round] TEST_100 的思路,我们维护一个区间 [l,r] 的答案,每次操作后,如果 l0r,我们就把 [l,0),(0,r] 中较小的一个区间向另一个区间合并,表示该区间的答案可以由另一个区间维护,具体只要连边建图即可。

注意到每个点只会被删除一次,因此复杂度 O(V)

时间复杂度 O(n+m+V)

Submission Link




11. [ARC149E] Sliding Window Sort

Problem Link

给定 n,m,k,对于 n 阶排列 a0an1,对于 i=0,,k1,我们依次对 a[imodn,i+mmodn) 升序排序,求有多少个 {ai} 操作后变成 {bi}

数据范围:n3×105

首先我们观察到,在 k=nm+1 时性质比较理想:此时 bnm+1bn1 恰好是 nm+2n

而前面的每个 bi 可以用堆维护,每次把 ai+m1 插入堆,然后弹出堆中最小值作为 bi

p=nm+1 那么我们先考虑如何把其他情况转成 k=p 的情况。

首先考虑 k<p,此时我们注意到所有操作只影响到了 ik+m1 的元素,可以只保留这段前缀并离散化作为新的 bi

然后考虑 k>p,此时我们要还原出 p 次操作后 bi 的样子,首先 nm+2n 在序列中一定占据 b[kmodn,k+m1modn)

然后观察剩下的序列 B=B[k+m1modn,kmodn),我们发现再操作一次相当于把 B 向右循环移位一位,那么 kp 次操作之前的序列 B 占据 b[0,p) 且相当于最终的 B 循环左移 kp 位。

然后考虑 k=p 时的答案,首先我们只要考虑 b[0,nm] 中的元素,因为 bnm+1bn1 就是 nm+2n

首先如果 bi1>bi,那么一定有 ai+m1=bi,否则第 i1 次就会把 bi 弹出,然后我们就可以删掉这些 bi,并不会影响整个过程中堆的变化。

然后我们在删除后的序列依然可以进行这样的操作,不停操作直到 bi 递增,此时从前往后每个 bi 都能随便填,每个数恰有 i+m1(i1)=m 种方法。

设原来的 B 中 Localmax 有 x 个,答案就是 (m1)!mx,其中 (m1)! 表示 nm+2n 可以随意填。

时间复杂度 O(n)

Submission Link




12. [ARC149F] Rational Number System

Problem Link

给定 p,q,求 1n 中在 pq 进制下字典序第 LR 小的数。

数据范围:n109,pq1.01

考虑把 1n 建 Trie,那么在一个数字串后面加一个字符 c 相当于 pxqx+c,例如 n=23,pq=1.5 的数字 Trie 形如下图:

注意到该 Trie 的 dfs 序即为字典序,因此我们在 Trie 树上 dfs,我们只要求出若干连续的儿子的子树大小之和,最终找到第 L 个点后按 dfs 序连续输出 RL+1 个数即可。

又因为这棵 Trie 的 bfs 序即为 1n,因此这些儿子 [x,y) 的子树在每一层上的标号都是连续的。

因此我们遍历每一层,求出 x,y 在该层的第一个儿子 xs,ys,那么该层的贡献就是 ysxs

可以 O(d) 暴力求,其中 d 是 Trie 的深度,dlog1.011092082

时间复杂度 O(d2logp)

Submission Link




13. [ABC260Ex] Colorfulness

Problem Link

给定 a1an,枚举所有 n 阶排列,对于所有 k=1mp(i=1n1[apiapi+1])k

数据范围:n,m2.5×105

根据 PGF 的一些理论,先求出权值的分布函数,即 fk 表示 [apiapi+1]=k 的排列数量,那么答案的 OGF 可以如下表示:

G(z)=i=0n1fij=0(iz)j=i=0n1fi1iz

这是经典问题,直接分治 NTT 维护分子分母,最后求逆一次即可。

fi 也是好求的,我们反面考虑求出钦定 k 对数相同的方案数 hk,二项式反演再反转序列即可。

i 的出现次数 ci,用形式幂级数枚举每个颜色内被钦定多少相同对:

hk=p1++pn=k(nkp1,p2,,pn)i=1n(ci1cipi1)ci!

同样分治 NTT 维护。

时间复杂度 O(nlog2n+mlogm)

Submission Link




14. [ABC261G] Replace

Problem Link

给定字符串 S,Tn 种操作,第 i 种可以把 S 中的字符 c 变成字符串 ai,求 ST 的最小操作次数。

数据范围:|S|,|T|,n,|ai|50

考虑 dp,先设 dpi,j 表示 S[1,i]T[1,j] 的最小代价,转移时我们要求 S[i,i]T[j+1,k] 的最小代价,因此设 fc,l,r 表示 cT[l,r] 的最小代价。

但是 fc,l,r 依然不好转移,考虑 c 的上一步,对于 |ai|=1 的变换,用 Floyd 提前处理出最短路更新,我们只要考虑上一步 |ai|>1 的情况。

那么进一步,我们可以设 gi,j,l,r 表示 ai[1,j]T[l,r] 的最小代价,转移就是 gi,j,l,rgi,j1,l,k+fai,j,k+1,r,然后内部转移 fc,l,r 通过 |ai|=1 的操作得到,再更新 gi,1,l,r

时间复杂度 O(|T|3|ai|)

Submission Link




15. [ABC261Ex] Game on Graph

Problem Link

给定 n 个点 m 条边的带权有向图,棋子初始在 s,双方不断移动棋子,先手想最小化棋子移动总路程,后手想最大化总路程,求最终棋子移动总路程。

数据范围:n,m2×105

先考虑朴素 dp:fu,0/1 表示当前轮到先手 / 后手,转移为:

fu,0=min(u,v)Efv,1+w(u,v)fu,1=max(u,v)Efv,0+w(u,v)

只有第一类转移的时候可以 Dijkstra 维护,每次弹堆就立刻得到 fu,0 的值,而 fu,1 我们需要滞后更新,记录 fu,1 的度数,直到所有入边都被处理后更新即可。

时间复杂度 O(mlogm)

Submission Link




16. [ABC262G] LIS with Stack

Problem Link

给定一个序列 a1an 求其最长的子序列,使得其可以通过单栈排序变成不降序列。

数据范围:n,ai50

考虑模拟入栈过程,对于 a1,如果其入栈,枚举其在 ai 入栈后出栈,那么把原问题划分成 a2aiai+1an 两个子问题,相当于加上值域限制 [1,ai][ai,V]

因此设 dpl,r,u,v 表示子序列 alar 在值域 [u,v] 中能得到的最长子序列,枚举 al 状态,首先有 dpl,r,u,vdpl+1,r,u,v

al[u,v],枚举其出栈时刻 i

dpl,r,u,v=mini=lr{1+dpl+1,i,u,al+dpi+1,r,al,v}

时间复杂度 O(n3V2)

Submission Link




*17. [AGC057C] Increment or Xor

Problem Link

给定一个 02n1 的排列 pi,每次可以把所有数 +1 后对 2n 取模或每个数异或上 x,构造一种操作方法,使得 pi=i

数据范围:n18

m=2n1,那么一个排列能还原的一个必要条件是 pipi+m(modm),即 pipi+m 的低 n1 位相同。

可以倒推证明:最终排列满足该性质,且对于两个低 n1 位相同的数,全体异或或全体 1 后低 n1 位依然相同。

那么说明原本的排列也必须满足 pipi+m(modm)

假如 p0pm1 的最高位都是 0,那么唯一的还原方法就是给每个数异或上 p0,可以证明这种情况下 +1 操作并没有用。

那么我们只要清空每个 p0pm1 的最高位,假如 pi 最高位是 1,我们可以把每个数异或上 pi 使得 pi=2n1 然后全体 +1 即可,此时其他 p0pm1 的低 n1 异或后都不可能是 m1(另一个低位是 m1 的元素是 pi+m),然后不断操作就能得到答案,操作数不超过 2n+1

只需要一个数据结构维护全局 +1,全局异或和单点查值,用 01-Trie 维护,全局加一相当于把一条链上的点交换左右儿子。

时间复杂度 O(n2n)

Submission Link




18. [ARC150E] Weathercock

Problem Link

给定 n×k 个人和 LR 构成的字符串 S1Sn,第 i 个人初始朝向为 Simodn

接下来进行 101000 次操作,每次同时考虑每个人 i

  • 如果 i 朝向左,且他左侧朝向右的人严格大于他左侧人数的一半,那么 i 转向右。
  • 如果 i 朝向右,且他右侧朝向左的人严格大于他右侧人数的一半,那么 i 转向左。

求最终所有人转向次数的总和。

数据范围:n,k2×105

先考虑 k=1 的情况。

考虑把 R 当成 1,L 当成 1 求序列前缀和 si

不妨设 sn0 否则可以通过翻转序列的方式取反 sn

那么我们能得到如下性质:

  • 对于一个初始朝向左的人 i,他会转向当且仅当 si0

  • 对于一个初始朝向右的人 i,他会转向当且仅当 snsi<0

si 的折线图画出来,能够发现(图源官方题解):

那么对于 si>sn 的所有 i 都要转向(红、蓝部分),而 snsi0 时只有向左的人要转向(黄色部分)

那么操作一次之后 sn 变成了最大的,那么可以证明之后 sn 也总是 smax,因此所有向右的人都不会被转向。

而对于一个向左的人 i,如果 s1si 中有正数,那么最终一定存在某个时刻使得 si0 从而令其转向。

因此我们可以得到如下规律:

  • 如果 i 初始向右,那么当且仅当 si>sn 时转向两次。
  • 如果 i 初始向左,当且仅当 maxs[1,i]>0 时转向一次。

然后考虑 k>1 的情况,i 初始向右可以解不等式求第一次 si>sni 初始向左那么 maxs1,[i+n]sn>0

因此可以直接求解。

时间复杂度 O(n)

Submission Link




19. [ARC150F] Constant Sum Subsequence

Problem Link

给定值域 [1,n] 的序列 a1an,构造无穷序列 Ai=aimodn,给定 m,求最小的 k 使得 A[1,k] 中包含所有和为 s 的序列作为子序列。

数据范围:n1.5×106,m2×105

考虑 dp,设 fs 表示序列和为 s 时的答案,那么有转移:

fs=min0<tssuf(fst,t)

其中 suf(i,x) 表示 A(i,+]x 首次出现的位置。

注意到该式子不好优化转移,可以考虑 CDQ 分治。

对于 flfmidfmid+1fr,我们可以枚举 t,然后我们发现 suf(fl,t)suf(fmid,t) 构成若干区间,每个取值点都是 t 的某个出现位置。

不妨设 pre(i,x) 表示 A[1,i]x 最后一次出现的位置,那么 k=pre(fmid,t) 是最后一个 suf(fx,t)=suf(fmid,t) 的位置。

进一步观察到 suf(fx1,t)fmid,这是显然的,因为 suf(fmid,t)fmid 之后第一次出现 t,那么 t 的上一次出现一定在 fmid 之前。

又因为 fi 有单调性,因此 suf(fl,t)suf(fx1,t) 这一部分的贡献直接用 fmid 滚一遍前缀最大值即可替代。

suf(fx,t)suf(fmid,t) 的贡献只需在 fx+t 上打标记,然后求前缀最大值的时候释放标记即可。

注意到 pre(i,x),suf(i,x) 都可以二分求出,注意一些小细节的分讨即可。

时间复杂度 O(mlogmlogn)

Submission Link




20. [ARC151F] RGB Card Game

Problem Link

给定三种卡牌,两个人分别有 (a1,a2,a3)(b1,b2,b3) 张,每次先手打出一张手牌,后手可以选择轮空,或打出同类手牌然后下一轮自己先手,T 次询问求最终谁会赢。

数据范围:T105

首先一步显然的操作是如果某种牌后手没有,那么先手一定会先把这种牌打完。

然后我们可以猜测答案本质不同的状态不多,且大多数状态都具有等价关系,记 ci=min(ai,bi),那么划分等价类的条件只有:

  • ai,bi 是否为 0 以及大小关系。
  • ci 的大小关系,cicj+ck 的大小关系,ci 的奇偶性。

注意到这些等价类中至少有一种情况可以落入 V10 中,爆搜求出所有 ai,bi10 的全部状态的答案即可。

时间复杂度 O(T)

Submission Link

posted @   DaiRuiChen007  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示