2021牛客多校部分题解

day2

G

  • 首先需要发现对于包含其他区间的大区间来说,要么自己新成立一个区间,最优选择是自己形成一个组,或者分在包含的小区间的那个组内。这步转化还是挺难的啊。。。
  • 把大区间先都筛出来。
  • 对小区间排序后dp,因为小区间两两之间不包含,所以在左端点升序后,右端点也是升序的。dp[i][j]表示前i个区间分为j组,先枚举j再枚举i,可以单调队列优化。
  • 最后贪心的添上大区间即可。
  • 再次感叹jiangly代码写的真短!

J

  • 这题需要Pollard-Rho+快速乘。
  • 容易想到从质因子的角度考虑答案。
  • p是当前考虑的质因子,f[p^i]是整除p^i且不整除p^{i+1}的数个数。
  • 那么对答案的贡献是p^{f[p]+2*f[p^2]+3*f[p^3]+\dots}
  • 直接枚举p^i对答案的贡献会使用多次乘法卡常。
  • 需要一个trick,考虑定义g[p^i]是整除p^i的数个数。
  • 那么对答案的贡献是p^{g[p]+g[p^2]+g[p^3]+\dots}。使用单次乘法不卡常。
  • 教训就是想清楚再写代码,不然总会出现很多错。不利于身心健康。

L

  • 根号分治即可。
  • 注意没有人步数超过10000,可再次优化。

day3

B

  • 转成n个行和m个列共n+m个点,(i,j)表示第i行和第j列之间的边。行和列内部均没有连边。求最小生成树。
  • y1s1这个模型挺神。

C

  • 如果b[i]=c[j]那么(i,j)这个格子可以当两个格子用。
  • 算一下二分图最大匹配。
  • 容易分析任意形式的最大匹配都是最优的。

G

  • 考虑离线做法,对于询问x,暴力之前所有x的倍数进行修改。
  • 将节点u修改为颜色x时,需要将u子树全部插入颜色x。这部分用树状数组套线段树维护。外层树状数组维护dfs序,内层线段树维护颜色。
  • 询问u时,倍增u的祖先,答案节点是t,那么对于颜色区间[L,R]t在该区间内的个数与u相同,且t是距离u最近的祖先。
  • 卡常使我痛苦。比赛时如果被卡常,需要快速止损,采用常数最小的方式。

day4

AK

A

  • 这题正解不会,因为点数不多,猜测最短递推式不长,考虑用BM整一下。
  • dp[i][j]表示以i为根的子树,学分和为合法的第j小的方案数。如果x是最小合法权值,那么第j小的学分为x+j。这部分需要带一些偏移量,我觉得挺不好想的。
  • 然后就是套一下BM。设dp[i][j]其中j的最大值取到1500,由于边界的细节问题,那么BM只用到dp[1][j](1\leqslant j \leqslant 1000)
  • 真难。

B

  • dp[i]表示当前序列最后一个数是i且生成数的过程仍未结束,将要生成的数的个数的期望。
  • dp2[i]表示当前序列最后一个数是i且生成数的过程仍未结束,将要生成的数的个数的平方的期望。
  • dp[i]=\sum_{j=1}^{i-1}p_j*1+p_i*(dp[i]+1)+\sum_{j=i+1}^{n}p_j*(dp[j]+1)
  • 根据E((x+1)^2)=E(x^2)+2*E(x)+E(1)得下式。
  • dp2[i]=\sum_{j=1}^{i-1}p_j*1+p_i*(dp2[i]+2*dp[i]+1)+\sum_{j=i+1}^{n}p_j*(dp2[j]+2*dp[j]+1)
  • 倒序求解期望。
  • dp2[1]即为答案。

C

  • 不妨设a\leqslant b \leqslant c
  • 先把长度为a的前缀都设置为相同并去掉。
  • 如果b-a+c-a\leqslant n-a即可构造出答案。
  • 证明有点麻烦,可以基于b+c-n > a无解来证明。

D

  • k条边相当于把树划分为k+1个连通块。
  • 考虑将每个连通块看成一个整体的点,然后对于k+1个连通块进行连边的方案数\prod_{i=1}^{k+1} {s_i}^{d_i},其中s_i表示第i个连通块的大小。d_i表示第i个连通块的度数。 
  • 考虑prufer序列,对于s_i都确定后的贡献,p_i表示i在 prufer序列中的出现次数。 

\begin{aligned} \sum_{tree(k+1)}\prod_{i=1}^{k+1} {s_i}^{d_i} &=\sum_{tree(k+1)}\prod_{i=1}^{k+1} {s_i}^{p_i+1} \\ &=\prod_{i=1}^{k+1} {s_i}\sum_{tree(k+1)}\prod_{i=1}^{k+1} {s_i}^{p_i}\\ &=\prod_{i=1}^{k+1} {s_i}(\sum_{i=1}^{k+1} s_i)^{k-1}\\ &=\prod_{i=1}^{k+1} {s_i}*n^{k-1}\\ \end{aligned}

  • 考虑如何计算\prod_{i=1}^{k+1}s_i,该问题等价于每个连通块选择1个点的方案数。
  • 考虑tree\;dp解决。
  • 定义dp[i][j][0,1]i子树有j个连通块且i所在连通块选择了0,1个点的方案数。
  • 因为j\leqslant k+1,因此复杂度是O(n*k)。树上背包的复杂度。
  • 挺难的,这我是真想不到。

E

  • 考虑w_1=0dfs一遍获得每个点的点权w_i
  • 然后令每个点权都异或a,每个点的点权变成w_i \oplus a \in [l[i] , r[i]]
  • 变形得w_i \oplus [l[i],r[i]] = S_i。其中S_i包含log(w_i)个连续的区间。
  • 答案是\cap_{i=1}^{n}S_i的区间长度和。
  • S_i采用类似于线段树的方法递归求解,原理是低k位是[0,2^k-1]的区间异或某个数后仍然是一个连续的区间。
  • \cap_{i=1}^{n}S_i可以采用Trie树,复杂度是O(n*logn)。或者采用区间排序差分求解,复杂度是O(n*logn*logn)

F

  • 每个操作都会更改边数与点数的和的奇偶性。
  • 因此判一下边数与点数的和的奇偶性即可。

G

  • \frac{D!}{\prod_{i=1}^{n}(a_i+k)!}=\frac{(D+n*k)!}{\prod_{i=1}^{n}(a_i+k)!*\prod_{i=D+1}^{D+n*k}i}
  • 难点在于求解\frac{(D+n*k)!}{\prod_{i=1}^{n}(a_i+k)!}
  • 把问题转化为将D+n*k个不同的小球放入n个不同的盒子且每个盒子至少有k个球的方案数。
  • 考虑容斥原理,使用dp计算至少有x个盒子小于k个球的方案数。 
  • 考虑文氏图进行容斥即可。

H

  • 快乐推式子。

i \otimes j = \frac{i*j}{gcd(i,j)^2}

b_k=\sum_{i\otimes j=k}a_i*j^c

i=i^{'}*d,j=j^{'}*d,m=min(\frac{n}{i^{'}},\frac{n}{j^{'}})

\begin{aligned} b_k &= \sum_{i^{'}*j^{'}=k,gcd(i^{'},j^{'})=1}\sum_{d=1}^{m}a_{i^{'}*d}*(j^{'}*d)^c \\ \end{aligned}

i^{'},j^{'}可以暴力枚举,考虑快速算后者。

\begin{aligned} f(i^{'},j^{'},m)&=\sum_{d=1}^{m}a_{i^{'}*d}*(j^{'}*d)^c\\ &={j^{'}}^c\sum_{d=1}^{m}a_{i^{'}*d}*(i'*d)^c &={j^{'}}^c*g(i^{'},m) \end{equation}

暴力预处理g(i^{'},m)即可。

  • 有点卡常。

I

  • 操作只会更改(i,i+1)的逆序对。
  • 因此如果消除了(i,i+1)的逆序对,下一个可能更改的逆序对是(i+2,i+3)
  • 贪心从前往后扫一遍即可。

J

  • 通过整理式子可知答案是序列a长度至少为x的连续子序列的最大平均数加上序列b长度至少为y的连续子序列的最大平均数。
  • 二分求解即可。

day5

C

  • 容易想到需要独立计算出单个f_i{(S)}
  • 容易想到采用调和级数的复杂度计算f
  • 定义cnt\_w[i]表示[1,i]W的个数,cnt\_l[i]表示[1,i]L的个数。
  • 定义pos\_w[i]表示第iW的位置,pos\_l[i]表示第iL的位置。
  • 定义nxt[i]表示游戏进行完第i球后当前局的状态是平局,且满足max(cnt_W,cnt_L)满足要求,需要进行到第nxt[i]球当前局会结束。判定s[i+1]=s[i+2]是否成立,倒序dp计算即可。
  • 细节很多,要考虑清楚,实在不行就写个对拍。 

E

  • 考虑离线枚举dtree \; dp
  • 不能枚举位进行转移,需要推一下O(1)的转移,有点麻烦,不过不难。

G

  • 无数种暴力方法,可是我一种也不会。翻了翻别人写的代码,发现一种神奇的搜索。
  • 转化一下问题,a+x取到一部分p_i^{q_i},这部分\Pi p_i^{q_i}记作s,然后b+y取到另一部分p_i^{q_i},这部分\Pi p_i^{q_i}记作t,要求gcd(s,t)=1。因此问题转化为求a+xs的倍数且a+xc的约数的最小的x
  • 考虑用搜索的思路解题,用mask记录a+x的质因子状态,其中第i位是1表示p_i的幂次是q_i,第i位是0表示p_i的幂次小于q_if_{mask}(a)表示当前状压的状态是mask时的最小的x。计算f_{mask}的复杂度是O(2^{\lceil{\frac{n}{2}}\rceil}),我口胡的复杂度,不会严格证明。
  •  只计算f不足以解决问题,因为a+xb+y的状压状态可能存在重复部分,即mask(a+x)\&mask(b+y) \neq 0
  • 考虑关于位的dp。定义g_{mask}=max(f_{mask2}),其中mask2\&mask=mask。这部分复杂度是O(n*2^{n})
  • 答案为min(g_{mask1}(a)+g_{mask2}(b)),其中mask1 \oplus mask2 = 2^n-1

day6

A

  • 好久没写计算几何了,来一手,感觉写着挺有意思,就是debug有点累。细节很多开始没想清楚导致一直改改改。
  • 这个题就是分析出每条边消失的时间即可。
  • 然后由叉积可知面积是关于时间的二次函数。
  • 将询问离线,删除边和回答询问同时进行即可。
  • 时间复杂度是O(n^2+q*logq)
  • 写起来很累,重生菜狗队写了80行orz。

F

  • 很容易想到二分答案然后打出GG。
  • 观察到答案至少是最大的t_i。可以保证每个牛排至多在两个锅内制作。
  • 再观察到答案不会超过\lceil {\frac{\Sigma t_i}{m}} \rceil
  • 然后按照锅的顺序摆放牛排即可。

G

  • Min\_25筛魔改题。
  • f(i)=(c+1)*f(\frac{i}{p^c})+c*d(\frac{i}{p^c}),其中d是约数个数。
  • 出题人说这种形式也可以Min\_25筛一筛。
  • 对于质数来说,f(p^c)=c
  • g(n,\left| P \right|)就是质数个数。
  • S(n,j)=cal1(n,j)+\sum_{k>j}\sum_{P_k^c\leqslant n}f_1(P_k^c)*S(\frac{n}{P_k^c},j)+f_2(P_k^c)*S_d(\frac{n}{P_k^c},j)+(c>1)*f(P_k^c)
  • 其中cal1(n,j)=g(n,\left| P \right|) - g(P_j , \left| P \right|)
  • 根据递推式,f_1(P_k^c)=c+1,f_2(P_k^c)=c
  • S_d(n,j)=cal2(n,j)+\sum_{k>j}\sum_{P_k^c\leqslant n}f_1(P_k^c)*S_d(\frac{n}{P_k^c})+(c>1)*f(P_k^c)
  • 其中cal2(n,j)=2*(g(n,\left| P \right|) - g(i,\left| P \right|))

H

  • 将所有矩形对d取模。
  • 注意判定矩形的长宽与d的关系。
  • 对矩形的左边界和有边界打上差分标记。
  • 将列从左往右扫,权值线段树存储当前列的行信息。
  • 查询当前列是否存在最小值是0的行。

I

  • 设输入的区间覆盖的部分的点集是S,构造的区间集合是T
  • 考虑S有多个未被覆盖的区间。称这些区间为空白区间。
  • 设第i个空白区间是[x,y](x\leqslant y)T的第i个答案区间是[y+1,x-1]。即构造的每个答案区间都留出一个空白区间。
  • 需要向T中加入[1,n]这个区间,解决没有空间区间的case

J

  • n是偶数直接输出即可。
  • n是奇数,将与非割点相连的边都删除,或者将与单个割点相连的所有边都删除。
  • 证明后者的正确性。容易发现最优局面是多个偶数个节点的连通块和多个孤立点,这些孤立点都是原图的割点。其中孤立点的个数是奇数个,否则会与n是奇数矛盾。大于1的奇数个孤立点可以转为1个孤立点,接着证明,如果孤立点个数大于1,建立关于孤立点的虚树,容易发现将与叶子节点的孤立点的边都删除即可,因此孤立点个数为1
  • 写代码时只要判定与割点相连的连通块的节点树都是偶数即可。

day7

J

  • 考虑bitset优化暴力。
  • ndij算出正确的答案。
  • 考虑模拟错误floyd的过程。枚举起点i,定义f[i][j]=true表示计算出正确的i,j路径,定义g[j][i]=true表示计算出正确的i,j路径。s[j][k]=true表示kij的最短路径上。
  •  考虑bitset优化上述几个数组,如果f[i]\&g[j]\&s[j]至少存在一个1就可以计算出正确的dis[i][j]
  • 仿佛暴力O(n^3)过不去,只要整成O(\frac{n^3}{w})就能过了啊!这是一个刻骨铭心的套路啊!

day8

A

  • ans = \Pi (1-p_i) (x_i\neq 0)

D

  • a+b=a|b+a\&b
  • 按位考虑即可。

E

  • 闰年不可能是质数。
  • 输出no。

F

  • ok[x1][y1][x2][y2]=true表示(x1,y1)可以到达(x2,y2)
  • [x1]这一维可以滚动掉。
  • [x2][y2]这两维可以压成一维然后用bitset优化。
  • 暴力都不会,是谁的问题呢?

H

  • 首先分析可知F是积性函数,然后拆开F。不过似乎这种题都是积性函数,假如你觉得积性函数能做的话,那它就是积性函数?
  • F(p_1^{k_1}p_2^{k_2}\cdots p_t^{k_t})=F(p_1^{k_1})F(p_2^{k_2})\cdots F(p_t^{k_t})
  • 考虑分析单个质数p
  • \begin{aligned} G_{p}(x)&=F(p^0)+F(p^1)x+\cdots \\ &=(\varphi(p^0) + \varphi(p^1)x + \cdots)^m \\ &= (1+\sum_{i=1}^{n}(p^i-p^{i-1})x^i)^m\\ &=(\frac{1-x}{1-px})^m\\ \end{aligned}
  • 上式最后一步转化用等比数列求和即可。
  • 答案是\Pi G_{p_i}(x)的第n项。
  • 分母表达了线性递推的性质,然后暴力求前面m*t项,通过分母进行快速递推即可。

J

  • 题目规定两人不能移动到同一个点,这种情况可以不考虑。
  • 需要发现一个事情,设s,t之间的路径是p,当两者之一离开路径后,两者之间将不再影响,也就是不再发生博弈。两者分别走能走的最长路,按照要求作差,对答案做出贡献即可。
  • 当两人同时沿着路径走了x步后,此时先手可以选择离开这条路径,此时贡献是ps[x]
  • 当先手走了x+1步后,后手走了x步后,此时后手可以选择离开这个路径,此时贡献是pt[x]
  • 博弈的本质是,ps[x]=min(ps[x],min_{i=1}^{y<x}pt[x]),即后手可以“制止”之后先手对自身更优的操作。
  • 答案就是最大的ps[x]
  • 写法参考jiangly,写的简直是艺术品!

K

  • 答案的路径肯定是大部分沿窄边走,少部分沿着对角线走。或者大部分沿对角线走,少部分沿着窄边走。
  • 暴力枚举少部分个数。

day9

G很诡异,因为节点到根的概率已经乘上去了。如果先乘逆元再乘会有0的问题。如果用前缀积与后缀积预处理也会出错。感觉拿任意两份ac代码出来对拍,都会出来不同的答案。先咕了,这个题是好题,就是数据太弱了,由此出来各种奇葩做法,然后给我整蒙逼了。

C

  • 根据LGV引理,构造如下行列式。
  • D= \left| \begin{array}{cccc} \begin{pmatrix} a_1+1 \\ 1 \end{pmatrix}&\begin{pmatrix} a_1+2 \\ 2 \end{pmatrix}&\cdots&\begin{pmatrix} a_1+n \\ n \end{pmatrix}\\ \begin{pmatrix} a_2+1 \\ 1 \end{pmatrix}&\begin{pmatrix} a_2+2 \\ 2 \end{pmatrix}&\cdots&\begin{pmatrix} a_2+n \\ n \end{pmatrix}\\ \vdots &\vdots&\ddots&\vdots\\ \begin{pmatrix} a_n+1 \\ 1 \end{pmatrix}&\begin{pmatrix} a_n+2 \\ 2 \end{pmatrix}&\cdots&\begin{pmatrix} a_n+n \\ n \end{pmatrix} \end{array} \right|
  • 不能直接高斯消元计算,考虑化简。
  • 每列提出一个\frac{1}{j!},得到det(D)=det(D^{'})*\prod_{j=1}^{n}\frac{1}{j!},其中D_{i,j}^{'}=\Pi_{k=1}^{j}(a_i+k)
  • 考虑行列式的初等列变换,用靠后的列减去靠前的列,得到D_{i,j}^{'}=(a_i+1)^j
  • 行列互换,行列式不变。那么D_{i,j}^{'}=(a_j+1)^i
  • 每列提出一个a_j+1。那么det(D)=det(D^{''})*\prod_{j=1}^{n}\frac{1}{j!}\prod_{j=1}^{n}(a_j+1) ,其中D_{i,j}^{''}=(a_j+1)^{i-1}
  • 因此det(D^{''})即为范德蒙德行列式。
  • det(D^{''})=\prod_{1\leqslant i < j \leqslant n} (a_j-a_i)
  • 考虑卷积快速统计a_j-a_i的个数然后快速幂得到行列式的值。
  • det( D)即为答案。

G

  • 很诡异,我现在懒得想了,想了好久了。感觉拿任意两份ac代码出来对拍,都会出来不同的答案。
  • 左边是st,右边是逆十字。我都蒙蔽了。

day10

G

  • 首先是一个子集反演。g(S) = \sum_{T \subseteq S} f(T),f(S) = \sum_{T \subseteq S} (-1)^{\left| S \right| - \left| T \right|} g(T)
  • f(S)表示集合S的人都被成功命中的概率。g(S)表示成功命中的集合是S的子集的概率。
  • 值得一提的是,当\left| A \right| = \left| B \right|时,f(A)=f(B),g(A)=g(B)
  • g(S)=(1-p+\frac{p(\left|S\right| - 1)}{n-1})^{\left| S\right|}(1-p+\frac{p(\left|S\right|)}{n-1})^{n - \left| S\right|}
  • 简单解释下g,左边表示集合S内部的人进行不成功攻击和成功攻击集合S内其他人的概率,右边表示集合S外部的人进行不成功攻击和成功攻击集合S内的人的概率。
  • 然后f(S)=\sum_{i=0}^{\left|S\right|}(-1)^{\left|S\right|-i}C_{\left|S\right|}^{i}g(i),卷积计算即可。
  • 最后输出的时候要乘个组合数系数,然后问的是存活的人,但是f算的是不存活的人,所以要倒序输出。
  • 这题还是妙啊,分析一波在知道子集反演这个科技的情况下能想到这个科技,主要还是f不好算但是g好算。g能避免选中但是是否成功命中的问题,选中一个集合,即使不能成功命中每一个元素,但是成功命中的集合还是选中集合的子集,所以只要选中一个集合就好了,避免了是否能成功命中导致的成功命中个数问题。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值