跳转至

2021牛客暑期多校第四场

排名 当场过题数 至今过题数 总题数
26/1292 8 10 10

A

upsolved by JJLeo 2sozx

题意

n 个节点的树形背包,每个节点物品权值为 si,可以选任意数量的物品,但每个节点要求该子树所选物品数量不能小于 ci

q 次询问,选恰好权值为 w 的方案数有多少?

(1n1001si50ci1501q100w108)

题解

2sozx's solution

显然如果不考虑 ci 的限制,每个点的方案就是一个生成函数,记录为 figi

考虑 ci 这个限制,对于 gi 求逆与 fi 乘起来,删掉前 ci1 项的系数即可,考虑去维护这个 figi ,考虑通分,然后用 fi 减即可,多项式项数维护到 n×max(c) 即可,大点也能过。

考虑对于根的多项式,可以通过 BM 来计算 w 大的值,对于 w 很小的值需要直接用多项式来算,因为前面的数并不是一个完全的多项式,而是删来删去得到的多项式,复杂度 O(能过)

JJLeo's solution

如果不考虑 ci 的限制,每个节点的生成函数就是 11xsi,子树的生成函数就是把子树里所有点的生成函数乘起来。

对于 ci 的限制,考虑 dfs 完一个子树时把当前生成函数的低于 ci 次项全部删掉,那么对于每个子树的生成函数一定也是形如 fi(x)gi(x) 的。我们可以维护分别维护分子和分母,然后求出 hi(x)=fi(x)gi(x)modxci,得到新的分子 fi(x)gi(x)hi(x)。这里有两种方式求出 hi(x)

  • 多项式求逆。
  • 注意到 gi(x) 形如 1j(1xsj) 的形式,因此对 fi(x) 的前 ci 项做 01 背包的逆变换即可。

本题数据范围小,后者常数小,说不定比前者快,而且只需要三行,老好写了。

最后,需要用到线性递推与其对应生成函数的本质:

f(x)g(x)=h(x)​​,degf<degg​​,当 ndegg ​ 时:

[xn]f(x)=0=i=0degg[xni]h(x)[xi]g(x)

因此,对 g(x) 进行移项归一化等调整就可以得到线性递推系数,递推的初值即为 f(x)g(x)degg 项。

注意到根节点的生成函数 f1(x)g1(x) 有可能出现 degf1degg1,这样 f 除以 g 后会得到一个 degfdegg 项的多项式,这说明前 degfdegg 项并不能作为递推初值。

懒得写多项式除法,因此设 m=max(degf1,degg1),用同样的 01 背包逆操作求出其前 m 项,之后取前 m 项的后 degg1 项作为递推初值即可。

当时没有理解透彻,还去 BM 求递推系数,老蠢蛋了。

S=maxi=1nsiC=maxi=1nci,总时间复杂度是 O(C(nS)2+q(nS)2logw)

B

solved by JJLeo 2sozx

题意

无限选 [1,n] 的正整数,各有概率 pi,如果这次选的数比之前最大的数小则结束,否则继续选,求游戏轮数平方的期望。(1n100 )

题解

2sozx's solution

考虑将平方变为每一次增加一个等差数列的贡献,即 1++2i1=i2,这样如果在这个序列前面加一个数,总贡献变为

1+2(1++2i1)+(1++2i1)

这样我们只需要维护总贡献 fi,以及单位贡献 gi 即可转移。

gi=j=1i1p[j]+j=inpigi,fi=3j=1i1p[j]+2j=inpigi+j=inpifi

复杂度为 O(n)

不知道为啥n这么小

JJLeo's solution

考虑求出第一个数选 i 的 轮次平方的期望 fi 及 轮次的期望 gi,那么由 fj 转移到 fi (j>i) 相当于 fj 中每次的贡献都增加了 2,因此加上 2gj 即可,gjgi 的转移则很简单就不赘述了。

最后转移方程写出来移个项就可以得到一个 O(n) 的递推式了。

D

upsolved by JJLeo

题意

给定一颗 n 个节点的树,删去 k 条边,新增 k 条边,使得新图还是一颗树,求方案数。(2n5×1041kmin(100,n1))

题解

显然删掉 k 条边会分出 k+1 个连通块,设第 i 个连通块有 ai 个点,根据 prufer 序列,答案为:

i=1ndi=2k(k1d11,d21,,dk+11)i=1naidi

设生成函数:

fa(x)=i=1+1(i1)!aixi=i=1+1(i1)!(ax)i=axi=0+1i!(ax)i=axeax

则最终答案为:

[x2k](k1)!i=1k+1fai(x)=[x2k](k1)!i=1k+1aixeaix=[x2k](k1)!(i=1k+1ai)xk+1(i=1k+1eaix)=[x2k](k1)!(i=1k+1ai)xk+1e(i=1k+1aix)=[xk1](k1)!(i=1k+1ai)enx=(k1)!(i=1k+1ai)nk1(k1)!=nk1(i=1k+1ai)

因此只需求出所有可能的 (i=1k+1ai) 的和,到这里都是做过的原题 ARC106F,然后赛时卡死不会求了,寄。

考虑这个积的含义就是将树分为 k+1 个连通块,每个连通块各选一个点的方案数,因此就转化为了简单的树形背包,设 fi,j,0/1 表示以 i 为根的子树,不算当前连通块选了 j 个连通块,当前连通块是否选了一个点,最后答案就是 f1,k,1

总时间复杂度为 O(nk)

G

solved by JJLeo 2sozx

题意

i=1nai=DD!i=1n(ai+k)!,其中 ai0

(1n500k500D108)

题解

假设 k=0 ,式子等价于 ai 表示数字 i 选择了几次,一共有 D 个位置的所有排列,这个又等价于长度为 D 的数组,每个位置可以选择 n 个数,答案即为 nD

考虑转化式子,将其变为

i=1nai=D+nk(D+nk)!i=1nai!D!(D+nk)! 此时 aik ,因此考虑容斥,我们只需要考虑有 i 个数小于 k,和为 j 的个数有多少个,贡献即可 O(1) 计算。个数可以直接用背包计算。

另外还需要考虑这些不合法数字所占的位置,也是一个组合数,乘上即可,没乘这个 WA 了一发。

H

solved by JJLeo 2sozx

题意

x=ipiaiy=ipibi,定义一种新运算: xy=ipi|aibi|

现在给定 a1,a2,,an,定义

bi=1j,kn,jk=iajkc

b1,b2,,bn。(1n106)

题解

xy=ipi|aibi|=xygcd2(x,y)
bi=1j,kn,jk=iajkc=jkgcd2(j,k)=iajkc=jkd2=i,d=gcd(j,k)ajkc=d=1nj=1ndk=1nd[jk=i,gcd(j,k)=1]ajd(kd)c=d=1ndcj=1ndk=1nd[jk=i,gcd(j,k)=1]ajdkc

设:

f(j,k)=i=1kaijic

原式化为:

bi=j=1nk=1n[jk=i,gcd(j,k)=1]kcf(j,min(nj,nk))

O(nlogn) 枚举合法的 (j,k),再用 O(logn) 判断 gcd 是否为 1

另外枚举外层 j 时预先处理出所有的 f(j,×),这部分复杂度也是 O(nlogn) 的。

总复杂度是 O(nlog2n) 的,场上乱冲过了,据说这个值域有预处理后 O(1)gcd 的黑科技。

记录

0h:看F过的人贼多CSK、ZYF想F,MJX乱看,然后ZYF挂了一发,发现把 i 写成了 x,改了就过了,之后MJX把J写了,CSK给MJX讲了个C的做法,太对了就去写了,MJX喂了ZYF一个I的正解,MJX脑子一抽把正解改假了又给了ZYF,寄了一发,C第一发也寄了。

1h:MJX重写了个I,过了,CSK改了改C也过了,ZYF看E是个经典算法,又TMD被卡常了,改了改就过了,MJX旁边搁那儿推B式子,没用期望推属实是个小可爱。

2h:ZYF E写完了推了推B就推出来了,MJX直接爬去看G,改吧改吧式子喂给了ZYF,ZYF直接冲锋,然后忘记选位置还要乘一个组合数,改了就过了。

3h:ZYF看D就是个原题,prufer 序列推出了式子,硬往树形背包上靠但就是不会做,MJX想了个意义,大概差不多,有点歪,然后被ZYF日掉了,实际上是正解,之后就感觉不可做了。

4h:开始看我们开始觉得一点都不可做的H题,先乱想 + 打表浪费了半个小时,4.35 的时候MJX突然想到了奇怪的运算符等价于乘积除以 gcd2,然后 15 分钟极限推式子 + 写代码,就过了,最后终于过稳定过过题了,不容易。

总结

Dirt

F(+1):ZYF X战警
I(+1):MJX要想的深一点,优化很有可能是错的
C(+1):
E(+1):卡常,stl慎用
G(+1):逆元写错了

回到页面顶部