2024.9 做题记录

1.P7811 JRKSJ R2 你的名字。

不难,但是卡常 /tuu
首先对 k 根号分治,记阈值为 B1,对序列分块,记阈值为 B2

对于 kB1 的情况,可以直接枚举 k,然后转化成区间 min,这部分时间复杂度 O(nB1+m(B2+nB2))

对于 k>B1 的部分,考虑将一个询问拆成对于每个 x 询问 [l,r]kx 的最小值,一个询问会被拆成 O(VB1) 个。
改为从小往大加入后变成 O(n) 次单点改,O(mVB1) 次查询区间 min。
考虑先把 [l,r] 在同一个块内的询问暴力做,这部分时间复杂度是 O(mB2) 的。
然后剩下的询问都能被拆成一个块的后缀 min、一个块的前缀 min、一段块的区间 min。
考虑每个块维护前后缀 min,块间维护 ST 表,这样查询是 O(1) 的,修改 ST 表上只用改 O(i0n2iB2)=O(nB2) 个位置,是 O(nB2+B2) 的。
这部分总时间复杂度为 O(nB2lognB2+mB2+mVB1+n(nB2+B2))

总时间复杂度为 O(nB1+m(B2+nB2)+mB2+mVB1+n(nB2+B2)),当 B1=VB2=n 时,时间复杂度为 O((n+m)(n+V))
卡常的话可以把 B1 开大一点。

2.SPOJ2939 QTREE5 - Query on a tree V

挺简单的,直接点分树就做完了。

3.P6688 可重集

记区间 [l,r] 的哈希值为:i=lrgai,这样就能快速至于平移 k 了。
不难发现 k=mini[l1,r1](ai)mini[l2,r2](ai),然后就做完了。
时间复杂度 O(nlogn)

4.CF1801F Another n-dimensional chocolate bar

fi,j 表示考虑了前 i 个,现在还要求 x>ibxj 时要求的式子的最大值。
转移为:

fi,jfi+1,jk×aik×1ai

我们比较习惯向下取整,所以可以改写为:

fi,jfi+1,j1k+1×aik×1ai

算一下状态数。考虑转移两次后,不难发现:

x1a+11b+1=x1ab+1

这也就是说,我们 DP 状态的第二位一定是 {k1x+1},也就是说第二维的大小是 O(k) 的。

再算一下转移的时间复杂度:

O(i=1ki+ki)=O(1k(x+kx)dx)=O(k34)

总时间复杂度 O(nk34)

5.CF504E Misha and LCP on Tree

先剖一下,然后每个询问就都被拆成了 O(logn) 段字符串。
按 dfn 序正反建 SA,然后就能快速求出两段字符串的 LCP,双指针统计答案即可。
时间复杂度 O((n+q)logn)

6.CF914F Substrings in a String

bitset 字符串匹配。
正解是分块 SAM 支持修改,查询通过根号分治处理。

7.P1222 三角形 and P3219 HNOI2012 三角形覆盖问题

首先我们可以将 x 轴切成 O(n) 区间,使得每个区间中只有 O(n) 个梯形。
将三角形按 y 排序,扫描每个区间统计答案即可。
时间复杂度 O(n2)

还有一种 O(nlogn) 的做法。
首先按 x 排序,维护当前 y 轴上所有的不交的被覆盖的区间。
现在要做的就是三件事:

  • 插入一个三角形。
  • 删除一个三角形。
  • 分裂一段区间。

可以用 set 维护。
插入的时候先把所有被它包含的删掉,然后再插入。
删除可以直接删。
分裂的话可以维护相邻两个三角形的交的大小,如果最小的为 0 就删掉原本的区间后再插入新的区间。

分析一下时间复杂度。
一个三角形最多被插入 1 次,所以插入的时间复杂度是 O(nlogn) 的。
同理,删除也是 O(nlogn) 的。
对于分裂,发现插入一个三角形最多会造成 2 次分裂,所以时间复杂度也是 O(nlogn) 的。
总时间复杂度 O(nlogn)

8.P5291 十二省联考 2019 希望

过了!赢!

首先的第一想法是把包括每个点的答案算出来然后相加,但这样会算重。
但是你发现,对于一组方案, 它能到达的点一定是一个连通块,我们想让它只被算一次。这个可以点边容斥 1=VE

也就是说,我们要把每个点和每条边的答案算出来相减。
考虑 DP:记 fu,i 表示选出一个在 u 子树内且最远点与 u 距离不超过 i 的包含 u 的连通块方案数,gu,i 表示选出一个在 u 子树内且最远点与 u 距离不超过 i 的包含 u 的连通块的方案数。
转移为:

fu,ivson(u)(1+fv,i1)gu,igfau,i1vson(fau)vu(fv,i2+1)+1

然后点的贡献为 (fu,Lgu,L)kufau 这条边的贡献为 (fu,L1(gu,L1))k

现在的问题是优化这个东西,显然要长链剖分。
depu 表示 u 到子树内离他最远的叶子的距离。

先考虑 f。发现虽然 f 第二位的范围是 O(n) 的,但是 [depu,n] 这一部分的值都是相等的。
思考一下我们要支持什么操作:后缀乘,全局加,单点乘。
不难想到用带 log 的数据结构维护,但是我们要线性。
对于后缀乘操作,我们对前缀的每个点乘上它的逆元,然后就变成全局乘了。
对于乘 0 的情况,我们可以维护 (limu,valu) 表示 fu,limu=valu,然后能简单维护。
现在的问题是求逆元,不难发现需要求逆元的位置只有 fu,depu1,所以可以预处理后 O(n) 求出所有逆元。
这样对 f 的转移就做到了线性。

然后考虑 g。发现 g 的第二位只需要维护 [max(0,Ldepu),L] 即可转移。
考虑长儿子继承父亲的答案,短儿子暴力转移,这样就做到了 O(depu)=O(n) 转移。
发现求 g 需要求 f 的前后缀乘积,而 fu 的前缀乘积是 ffau 做到 u 这个儿子前的值,后缀乘积我们可以简单维护,所以只需要支持对 f 的可撤销。

具体的说,我们先在求 f 的时候,把在每个点对 f 的影响记下来。
然后在求 g 的时候,按照和 f 相反的顺序做,每次把当前儿子的影响撤销,这样 f 中存储的就是前缀乘积。然后将对应儿子的 f 的值乘到长儿子的 g 上,这样长儿子的 g 中存储的就是当前的后缀乘积。
这样我们就实现了求前后缀积,剩下的按式子转移即可。

时间复杂度 O(n)

9.P8557 炼金术(Alchemy)

考虑将每种金属往熔炉里放,这样方案数就是 (2k1)n

10.P5303 GXOI/GZOI2019 逼死强迫症

不难发现,如果固定了两个 1×1 的砖块的位置分别为 l,r(rl>1),那么第 [l,r] 列的放法就固定了,第 [1,l1][r+1,n] 列的方法是斐波那契数列。
所以答案的式子是:

ans=2r=3nFibnrl=1r2Fibl1=2r=3nFibnr(Fibr11)=22Fibn1+2i=0n3FibiFibni1

如果记 Sn=i=0nFibiFibni,那么有:

ans=2+2Sn14Fibn12Fibn2

矩阵乘法即可。
时间复杂度 O(ω3logn+Tω2logn),其中 ω=4

11.P7706 「Wdsr-2.7」文文的摄影布置

首先观察到,因为求的是 ϕ(l,r) 的最大值,所以 min(Bj) 是没用的,因为取到最大时 Bj 一定最小。
然后就可以线段树简单维护了。
时间复杂度 O(qlogn)

12.P6327 区间加区间 sin 和

直接线段树。

13.P5278 算术天才⑨与等差数列

判定条件是:

  • k0gcd(al+1al,al+2al+2,,arar1)0(modk)
  • maxi[l,r]aimini[l,r]ai=(rl)×k
  • k0a[l,r] 互不相等。
    直接线段树维护即可。
    时间复杂度 O(nlogV+q(logn+logV))

对每个 ilsti 表示 maxj<iaj+ai=wj,查询就是查 lst 的区间 max
然后发现这样修改不了。
你发现你修改不了的原因是你会影响到下一个 ai 之间的所有满足 aj+ai=w 的数,但是这些里面只有第一个是对答案有影响的,其他的一定不优,所以把其他的 lstj 赋值为 0 即可。
时间复杂度 O((n+q)logn)

15.P4344 SHOI2015 脑洞治疗仪

区间覆盖,区间最长连续 0 子串。

16.P2572 SCOI2010 序列操作

17.P4146 序列终结者

18.P7738 NOI2021 量子通信

首先发现,由于 k15,所以如果我们对每个串按 B=16 分块,那么至少有一块询问串和字典串是相同的。
由于数据随机,对于查询串的一块,字典串中与这一块相同的串的期望个数为 6.103515625。
所以暴力枚举询问串的每个块,找字典串中与他相同的判断即可。

20.P8576 「DTOI-2」星之界

不难发现,操作二的答案是:

(i=lraial,,ar)=(i=lrai)!i=lrai!

只需维护区间和、区间每个数阶乘的乘积。

看到操作一不难想到分块,这部分是简单的。
注意每块的并查集不能对每个颜色维护,而是要对每个位置维护它与哪个位置颜色相等。如果按前一种方法维护,那么 xyzx 之后 z 的颜色无法维护。

时间复杂度 O(qn)

21.P8321 『JROI-4』沈阳大街 2

相当于把 AB 两两匹配,贡献为没对匹配较小的数的乘积。
所以我们把 AB 拼起来,从大到小排序,在后面的数的位置计算贡献即可。

考虑 DP。设 fi,j 表示前 i 个数,匹配了 j 对的贡献之和,转移为:

fi,jfi1,jfi,jfi1,j1×ai×(cnt1typei,i1(j1))

答案为 fn×2,n/n!

时间复杂度 O(n2)

22.P1641 SCOI2010 生成字符串

看成初始在 (0,0),当前在 (x,y),如果选 0 就走到 (x+1,y1),如果选 1 就走到 (x+1,y+1),最后在 (n,nm) 且纵坐标始终不小于 0 的方案数。
答案为 (n+mm)(n+mm1)

23.P3773 CTSC2017 吉夫特

先按 Lucas 定理分解一下。记 abi 的二进制分解的第 j 位为 ci,j,则有:

i=2k(abi1abi)i=2kj(ci1,jci,j)(mod2)

这就要求每个 (ci,jci1,j) 都不等于 0,也就是说 ci1,jci,j,也就是说如果把二进制看成集合,那么 abiabi1

考虑 DP。记 fi 表示以 i 结尾的方案数,那么转移为:

fij>iajaifj

可通过枚举子集做到 O(3logV)

24.P8688 蓝桥杯 2019 省 A 组合数问题 and P6669 清华集训2016 组合数问题

先按 Lucas 定理分解一下 (nm),不妨 n=iaikim=ibiki,那么有:

(nm)i(aibi)(modk)

那么 (nm)=0i,ai<bi
存在一个不好算,改为算 i,aibi

考虑数位 DP。设 fi,0/1,0/1 表示考虑了高 i 位,a 贴 / 不贴上界,b 贴 / 不贴上界的方案数。
转移为:

fi,1,1[aibi]fi+1,1,1fi,1,0fi+1,1,1×min(ai+1,bi)+fi+1,1,0×(ai+1)fi,0,1[ai>bi]fi+1,1,1×(aibi)+fi+1,0,1×(kb)fi,0,0flen+1,1,1×calc(a,b)+flen+1,1,0×calc(a,k)+flen+1,0,1×calc(k,b)+flen+1,0,0×calc(k,k)

其中:

calc(n,m)=i=0n1j=0m1[ij]={n(n+1)2,if nmm(m+1)2+(nm)m,else

时间复杂度 O(logkn)

25.P8594 「KDOI-02」一个仇的复

不难发现只有 x=2 是特殊的,因为一个 2×1 的矩形是可以竖着填的,其他的矩形都只能横着填。
所以考虑枚举 2×1 的矩形个数 i,它将整个网格分隔成了 2×a1,2×a2,,2×aj (x=1jax=ni) 这些较小的网格。
不难通过插板得到分隔的方案数为:

(i+1j)

现在的问题是计算每部分的方案数。

先考虑对于一个 2×n 的网格,如果只允许横着放 k 个矩形,那么有多少种方法。(这个是上面的子问题)
不难通过插板法得到答案:

i=1k1(n1i1)(n1ki1)=i=0k2(n1i)(n1(k2)i)=(2n2k2)

第一步是枚举了第一行放多少个,第三步是通过范德蒙德卷积化简。

现在再考虑原问题,答案为:

x=1jbx=kix=1j(2ax2bx2)=(n2i2jni2j)

还是范德蒙德卷积。

此时,我们发现,在 i,j 相同时,对于每种 a 序列的答案都是一样的,所以我们只需要在求出 a 序列的方案数即可。
不难通过插板得到答案为:

(ni1j1)

所以答案就是上面三部分乘起来,即:

i=0kj=1k+1(i+1j)(ni1j1)(n2i2jni2j)

但是我们还有一种情况没有考虑到,就是 n=k 时我们可以全放 2×1 的矩形,所以真正的答案为:

i=0kj=1k+1(i+1j)(ni1j1)(n2i2jni2j)+[n=k]

时间复杂度 O(n+k2)

26.P8367 LNOI2022 盒

先考虑如果已经知道了 b 数组怎样算答案。

考虑对每个 wi 分别计算贡献。记 sai=j=1iajsbi=j=1ibj
则答案为:

i=1n1wi|saisbi|

不知道 b 的话可以枚举 sb 的每一项,剩下的是插板:

i=1n1wij=0S|saij|(j+i1i1)(Sj+ni1ni1)

然后分类讨论拆绝对值,这里只讨论 jsai 的部分,这样就转化成了求两个式子:

j=0k(j+i1i1)(Sj+ni1ni1)

j=0kj(j+i1i1)(Sj+ni1ni1)

第二个式子的形式是显然不如第一个好的,所以考虑把 j 吸收进去,转成第一个,变成:

i×j=0k(j+i1i)(Sj+ni1ni1)

后面的那个式子调一下 nS 就和第一个一样了。所以现在就只需要求第一个了,记其为 f(i,k)

因为 ik 都是单调的,所以考虑每次由 f(i,k) 变成 f(i+1,k)f(i,k+1)

变成 f(i,k+1) 是简单的,现在主要是解决 i 加一时的情况。

考虑 f(i,k) 的组合意义:有 n 个盒子,要放 S 个小球,前 i 个盒子中至多放 k 个球的方案数。

这个可以转化成第 k+1 个球恰好放在 i+1 几之后的盒子里。这样可以枚举第 k+1 个球放的位置,也是个插板:

f(i,k)=j=i+1n(j+k1j1)(nj+Sk1nj)

然后 i 加一就能做了。时间复杂度 O(T(n+S))

27.P4456 CQOI2018 交错序列

答案为:

i=0n(i+1ni)ia(ni)b

然后 iaib 可以线性筛一下,这样就线性了。

28.P4562 JXOI2018 游戏

对于 lir,如果 maxkik1(i/k)<l,那么我们称 i 是一个关键点。
不难发现,对于一个排列 πt(π)=maxπi is a key nodei
考虑利用 sum=E×cnt 来解决。
我们要求是关键点最大位置的和,不妨先求关键点最大位置的期望。

不妨记关键点的个数为 m
对于一个非关键点,它在所有关键点之后的概率为 1m+1
那么所有关键点之后的点数期望为:nmm+1
所以关键点最大位置的期望为:

nnmm+1=(n+1)mm+1

最终答案为:

(n+1)mm+1×n!=mm+1(n+1)!

关键点的个数可以线性筛出最小质因子然后计算。
时间复杂度线性。

29.P2606 ZJOI2010 排列计数

对于 i>1,连边 i/2i,这样就形成了一棵外向树,我们要求的就是树的拓扑序数量。
答案为:

n!isizei

注意要把每个数表示成 am+b 的形式再进行乘除运算。
时间复杂度线性。

30.P8863 「KDOI-03」构造数组

m=i=1nai,先把 2m 的情况判掉,然后令 mm/2

现在我们的问题是数长度为 m 的二元组序列 (xi,yi) 表示我们第 i 次操作操作了位置 xi,yi 的数量。
此时我们的要求是 xi<yi,i=1n([xi=j]+[yi=j])=aj
不妨将第一个条件变为 xiyi,我们最后将结果乘 2m 即可。

考虑容斥,钦定一个集合 S 满足 S 中的二元组满足 xi=yi,此时的容斥系数为 (1)|S|
现在的问题是算方案数。
考虑第二个条件,我们不妨记 ci 表示钦定的二元组中 xj=yj=i 的数量,满足 ci=|S|
那么贡献为:

(1)|S|(mc1,c2,,cn,m|S|)(2(m|S|)a12c1,a22c2,,an2cn)

其中第一个组合数是把钦定的位置分配到原序列中的方案数,第二个组合数是把未被钦定的位置分配到二元组中的方案数。

拆一下:

(1)|S|(mc1,c2,,cn,m|S|)(2(m|S|)a12c1,a22c2,,an2cn)=(1)cim!(m|S|)!ci!(2(m|S|))!(ai2ci)!=m!(2(m|S|))!(m|S|)!(1)cici!(ai2ci)!

不难想到记:

Fi(x)=j(x)jj!(2aij)!

那么答案即为:

m!2ms0(2(ms))!(ms)![xs]iFi(x)

暴力卷积可做到 O(m2),使用分治 NTT 可做到 O(mlognlogm)

31.P3266 JLOI2015 骗我呢

首先进行简单的观察,发现每一行都是 0,1,,m 这个序列删掉了一些数。
如果记第 i 行删掉了 ai,那么要求是 ai>ai12

考虑 DP,记 fi,j 表示考虑了前 i 行,aij 的方案数。
转移为:

fi,jfi1,j+1+fi,j1

画一下转移的形态,发现答案等价于从 (0,0) 走到 (n+m+1,n),每一步能向上或向右走,不经过 y=x+1y=x(m+2) 的方案数。
反射容斥即可。
时间复杂度 O(n)

32.P3197 HNOI2008 越狱

。。。

33.P6692 出生点

不想写了。

34.P1450 HAOI2008 硬币购物

直接列 GF:

ans=[xs]i=031x(di+1)ci1xci

然后暴力卷起来就行。
时间复杂度 O(ns)

当然你可以把分子暴力展开一下,这样就是 O(s+n2w),其中 w=4

35.P8290 省选联考 2022 填树

首先考虑枚举最小值 l,那么我们剩下的能填的最大值 r=l+k
但是我们恰好取到最小值不好做,所以我们进行容斥 [min=l]=[minl][min>l]
那么现在我们要求的就是值域是 [l,r] 的子集的方案数和权值和。

先枚举钦定的值域区间 [l,r],记 fu,0/1 表示 点 u 为根选一条链的方案数 / 点 u 为根的方案数,gu,0/1 表示 点 u 为根选一条链的权值和 / 点 u 为根的权值和。
考虑合并点 u 的儿子 v,记 w1=|[lu,ru][l,r]Z|w2=i[lu,ru][l,r]Zi,则转移为:

gu,1gv,1+fu,0×gv,0+fv,0×gu,0gu,0gv,0×w1+w2×fv,0fu,1fv,1+fu,0×fv,0fu,0fv,0×w1

时间复杂度 O(nV)

发现 w1 可以表示成关于 l 的至多一次的分段多项式,w2 可以表示成关于 l 的至多二次的分段多项式,每个点都会把左端点的值域分成至多 5 段,所以左端点值域总共被划分成了 O(n) 段,考虑对每段分别 DP。
考虑多项式次数上限。
先考虑 f
固定一个 l 时,f 就相当于选一条链,把链上的点的 w1 乘起来,这个是至多 n 次的。
然后我们对 l 做了一个前缀和,这个是至多 n+1 次的。
所以 f 的次数不超过 n+1
再考虑 g
固定一个 l 时,g 就相当于选一个点,把这个点的 w2 乘上这个点的贡献次数,贡献次数就是分别从以这个点为根时的两棵不同的子树中选一条链,将他们的 w1 乘起来,这个是至多 n+1 次的。
然后我们对 l 做了一个前缀和,这个是至多 n+2 次的。
所以 g 的次数不超过 n+2

直接拉插可以做到 O(n3)

还有一种常数更好的做法,是从第一篇题解里看到的,我实现了一下发现确实跑的飞快。
就是你考虑直接维护这个多项式,记 Fu,0/1(x) 表示 fu,0/1 对应的多项式,Gu,0/1(x) 表示 gu,0/1 对应的多项式,转移和上面的一样,时间复杂度就是树形背包的 O(n2)
现在要做的就是已知 f(x)=i=0naixi,求 x=0rf(x)
先变一下求和顺序:

x=0rf(x)=x=0ri=0naixi=i=0naix=0rxi

然后要求的就是 x=0rxk

x=0rxk=x=0rik{ki}xi_=ik{ki}x=0rxi_=ik{ki}i!x=0r(xi)=ik{ki}i!(r+1i+1)

这样就能 O(n2) 求了。
所以时间复杂度为 O(n3),但是常数会小很多。

36.P3746 六省联考 2017 组合数问题

我太唐了。下文基本 copy 自 https://www.luogu.com.cn/article/knllx86m

i(nkik+r)=imodk=r(nki)=imodk=r[xi](x+1)nk=[xr]((x+1)nkmod(xk1))

然后循环卷积快速幂,时间复杂度 O(k2logn)

37.24ZR CSP 七连 Day1

solution

38.24ZR CSP 七连 Day2

solution

39.基础检测赛

solution

40.24ZR CSP 七连 Day3

solution

41.2024 CSP-S 模拟赛 Day 6

solution

42.24 ZR csp 7连测day4

solution

43.22csp7连 day1

solution

44.22csp7连 day2

solution

45.22csp7连附加赛day1

solution

46.Codeforces Round 976 (Div. 2) and Divide By Zero 9.0

solution

posted @   definieren  阅读(17)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起