T3恶心死我了写了182行4.6K。
T1
联赛状压题。
我们发现\(m\)很小,那么状压。
设\(f[i][j][S]\)为第\(i\)个元素使用了\(S\)集合中的操作之后大小为\(j\)的概率。
那么我们可以写出转移方程。
设\(dp[i][j][S]\)为前\(i\)个元素使用了\(S\)集合中的操作之后,最大值的大小为\(j\)的概率。
相当于是一个多维背包计数。
那么有转移方程:
然后这个复杂度就是\(O(nm^2c^23^m+nm^2c^22^m)\)。
很卡常
然后我是个毒瘤做题人,有一些卡常技巧。
首先,可以用\(long\ long\)存储,取模次数减少一半。
第一个状压\(f\)的时候,我们发现转移顺序并不影响答案,所以我们可以每次枚举最高位转移,常数减小得多。
还有一个地方,我们枚举不一定要枚举到\(mc\),可以枚举到\(num[s]c\)。
T2
结论题。
我们考虑构造答案最小的数据。
必然是全局每个格点占满关键点。
那么这种情况只能留下一行或者一列的白色格子。
那么周长最多是:\(2(max(h,w)+1)\)
这个东西是大于:\(2(\frac{h}{2}+\frac{w}{2})=h+w\)的。
那么我们可以发现,我们的最终矩形必然是过中线的。
那么维护一个线段树。
我们考虑扫描线。
当扫描到某一个位置\(r\)的时候,线段树上下标\(l\)维护的是\([l,r]\)这一段中大于\(h/2\)的最小的\(y\),和小于等于\(h/2\)的最大的\(y\)。
考虑动态维护这个东西。
我们发现,随着区间\([l,r]\)的变大,上下的区间从\(h\)变小。
然而我们的\(r\)在向右,所以每个\(l\)位置的上下区间大小都是变小的。
那我们考虑用一个单调栈来维护这个东西。
每一个栈上的位置都在退栈的时候,更新一下自己的区间,什么是自己的区间,就是当自己为最大值或者最小值的那一段区间。
这一段区间中全部都减掉当前缩小的上下区间长度。
由于我们的\(r\)是变化的,所以初值可以变成\(h-l\),然后最终求值的时候给答案加上\(r\)即可。
T3
恶心的\(ddp\)。
我是从链的情况一步一步推出非链的情况的,貌似和题解推的差不多。
这里我自己推一次。
其实\(ddp\)最重要的就是构造矩阵,剩下的就是一个差量更新,毫无技术含量就是难写的要死。
那先说一下链的情况。
首先有:
设\(dp[i][j]\)为\(i\)位置是长度为\(j\)的链顶端的最大剖分。
设:\(f[i]=\max\limits_{j=1}^{L}dp[i][j]\)
那么设矩阵:
那么有:$$R[i]=G[i]R[i+1]$$
这样我们直接用线段树来维护。
修改的时候单点修改,查询全局矩阵就可以了。
尝试构造树上的情况。
设:
\(ch[x]\)为节点\(x\)的重儿子。
\(son[x]\)为节点\(x\)的儿子集合。
\(dp[x][i]\)为树上节点\(x\)为长度为\(i\)的链的顶端的子树最优剖分。
\(f[x]=\max\limits_{j=1}^{L}dp[x][j]\)
那么有\(dp\)的转移:
设\(g\)为轻儿子的一些贡献。
那么开始构造矩阵:
那么有:
考虑一下这个\(G\)矩阵究竟是怎么搞的。
第一行,我们把\(dp[x][1]\)的转移搞好,相当于在求出他们的最大值。
第\(i(i>1)\)行,我们把\(dp[x][i]\)的转移搞好,相当于在求出:
中的最大值。
这样的转移也符合我们的\(dp\)转移方程。
那么我们只需要套一个\(ddp\)的板子,然后求\(g[x][2……L]\)的时候用\(set\)来维护一下就行了。
这样复杂度就是\(O(qL^3log^2n)\)