CSP2019题解

CSP2019题解

格雷码

按照生成的规则模拟一下即可。

代码

括号树

看到括号匹配首先想到用栈,然后又在树上就可以想到可追溯化栈。 令$a_i=1$表示$i$号节点上的括号为(,否则为), 记栈为$stk$,其中元素个数为$top$。 设$f_i$表示加上节点$i$所对应的括号所增加的贡献,$g_i$表示这个点的答案,转移很显然:

[ egin{aligned} egin{cases} f_i=0&(a_{fa_i}=1)\ f_i=f_{fa_i}&(a_{fa_i}=-1)\ f_i=0&(a_i=-1,top=0)\ f_i=f_{stk_{top}}+1&(a_i=-1,top>0)\ g_i=g_{fa_i}&(a_i=1)\ g_i=g_{fa_i}+f_i&(a_i=-1) end{cases} end{aligned} ]

然后就没了。

代码

树上的数

Link

Emiya 家今天的饭

因为主要食材最大值只会有一个,钦定最大值是哪一个,又因为每一种烹饪手法最多选一次,设$f[i][j][k]$表示目前在第$i$中烹饪手法,现在做了$j$道菜,最多的食材用了$k$次,转移很显然就不写了,那么最后你把不满足要求的减掉就行了,这样子是$O(n^3m)$的。

考虑优化这个状态,设$f[i][j]$为目前在第$i$中烹饪手法最大值与其他的的差为$j$的方案数,和前面一样容斥就优化成了$O(n^2m)$的了。

代码

划分

有一个比较显然但是并不会证的结论就是令最后一段的和最小。

记数列前缀和为$s_i$, 设$f_i$表示$[1...i](最后一段最小时,最后一段为)[f_i,i]$,那么有转移

[ f_i=max j,{0leq jleq i-1,s_j-s_{f_j}leq s_i-s_j} ]

然后因为$s$单调,把这个式子化一下就是$2s_j-s_leq s_i$,注意到一个单调队列优化$dp$的形式所以直接用单调队列优化dp即可。

因为要高精度,所以只能用$f$数组往前推求答案。

代码

树的重心

注意一棵树的重心肯定是在其根节点所在重链上的,那么你每次断边时找到最深的满足条件的点$x$,因为如果重心有两个的话肯定是父子关系,所以再判断一下$fa_x$是不是满足条件即可,这样子的话复杂度$O(n^2)$。

考虑优化这个东西,在重链上构造一个倍增数组跳重链,然后每次像普通倍增一样即可,然后需要换根,复杂度$O(nlog n)$,细节见代码。

代码

原文地址:https://www.cnblogs.com/heyujun/p/11985198.html