题7

P3343 [ZJOI2015] 地震后的幻想乡

如果得知\(f_{U,k}\)表示选\(k\)条边把\(U\)联通的概率,我们钦定这\(k\)条边就是前\(k\)小条边,那么\(f_{U,k}-f_{U,k-1}\),就是恰好在第\(k\)条边的时候联通的概率,也就是最小生成树的最大边就是第\(k\)个边。由于都在\([0,1]\)中取值,所以第\(k\)小的期望就是\(\frac{k}{m+1}\),那么如果求出了\(f_{U,k}\)求出来就好了。那么容斥,枚举编号最小的点所在的连通块在哪里,然后这个连通块要联通,利用前面的信息,然后剩下的点就是随意,但是不能和这个连通块有连边。

总结:必须算出的是概率,不能是方案数,因为概率相当于相对于所有的排列的比例,但是方案数只考虑前\(k\)个,没有考虑后面边的方案,所以就不对了。求法就是可以先算方案数,然后让\(\frac{f_{U,k}}{\binom{m}{k}}\)就行了。

总结:这个容斥的方法比较经典,就是选一个特定的点,枚举其所在的连通块,然后考虑其他点的联通不连通

CF280C

考虑一个点什么时候会主动被删。那么我们把操作序列抽象成一个排列,从前往后,如果遇到一个没有被删的,那就删掉他,否则如果其祖先被删掉,就跳过他。所以一个点被删的概率就是他是他到链上的所有点第一个被遍历到的点,因为所有点被放到第一个的位置是相同的,所有其概率就是\(\frac{1}{dep}\),权值是\(1\),期望就是\(\frac{1}{dep}\)。所以期望总次数就是\(\sum\frac{1}{dep}\)

总结:期望可以用排列来刻画

P16573 [USACO26OPEN] Haybale Stacks

有点牛逼把。考虑所有\(p=1\)的情况,那么,所有的都可以随便用。找出一个性价比最高的,即\(\frac{s}{c}\)最大的。考虑最后使用这个值。对于一个干草垛\(x\),不使用这个值的操作最多有\(s\)个,因为操作序列 \(x_1\to x_2\to x_2\to\cdots\),把\(x\mod s\),那么如果出现了\(x_i\equiv x_j \pmod{s}\),那么我们就可以通过性价比最高的东西替换操作一定更优,所有操作序列最多有\(s\)项。特殊一点就是\(\max s\)项,每一个项的值最大为\(\max s\),所以这部分的长度最大是\((\max s)^2\),然后后部分答案可以通过跳最优的\(O(1)\)得到了。那么如果\(p\)不全等于\(1\),那么我们就从小到大枚举\(p\)。每增加一个\(p\),就会多一个可选的,并且更新最优点。刚刚的\(s^2\)我们是在所有点都考虑的情况下得到的结论,所以我们需要维护\(p_i+s^2\)\(dp\)值,这部分,1. 有前面直接继承过来,2. 选择新的可选点,转移是\(O(1)\)的,所以这部分复杂度是\(O(s^2)\)的,所以总复杂度就是\(O(MS^2+N)\)

总结:对于背包容量特别大,但是物品体积很小的东西,做法是前一部分\(dp\),后一部分贪心,具体做法就是上述的。

P14463 【MX-S10-T4】『FeOI-4』呼吸之野

这个真有点牛逼吧。出现了中位数,对中位数的维护方法:如果要一个序列的中位数\(\ge x\),那么就让\(<x\)的值变成\(-1\),让\(\ge x\)的值变成\(1\),那么合法的充要条件就是序列和\(\ge 0\)。那么我们现在假定中位数确定。记录\(s_i\)表示前缀和那么一个区间是合法的当且仅当\(s_r-s_{l-1}\ge 0\)。并且\(r-l+1\ge k\)。还有一个极小的限制。所以我们需要让\(l\)\(r\)单增。我们有要求\([L,R]\)中有多少个极小的。由于极小的性质,所有我们可以差分,就是维护\([1,r]\)中有多少个合法的\(r\)节点,和\([1,L-1]\)中有多少个合法的\(l\)节点,就行了。考虑怎么维护这个东西。维护两个类似指针的东西,\(r,r-k\)。两个都在不断右移。起始\(r\)\(k\)开始走。现在假设一开始\(s_r<0\)。两个同时开始走,如果前面都没有合法的\(r\),那么当前遇到合法的\(r\)有两种情况

  1. 就是和前面折线的\(\min\)相等(先不考虑\(s_{r-k}\)这个点)。由于是第一个合法的,所以他不可能适合\(>\min\)的遇上,因为变化都是\(+1,-1\),所以这个点想合法一定要先等于最小值,否则在之前一定有一个更早的合法的点。这种情况,由于我们要保证合法的左端点单增,所有我们要把最小值左边的砍掉。那么新的最小值呢?比较显然的就是当前最小值\(+1\)了。
  2. \(r\)恰好和\(r-k\)遇上了。那么当前\(r-k\)也就是最小值了,只不过我们需要把\(r-k\)前面的都删掉,也就是前面的最小值就被赋值成\(+\infty\)。当然我们可以直接看做把\(\min\to \min+1\),因为这种情况\(s_{r-k}\)恰好等于最小值,\(s_{r-k}\)的变化是\(+1,-1\),当\(+1\)的时候恰好就对了,当\(-1\)的时候,我们会把\(\min\)和当前的\(s_{r-k}-1\)\(\min\),所以更新也是对的,那么就不用分讨了。 。所以我们需要维护的就只有两个值\(a,b\)分别代表上一个合法的\(l\)到当前的\(r-k\)\(s\)\(\min\)\(s_{r-k}\)。变化是\(a+1,b\pm 1\)

判断合法的条件就是\(max(s_r-a,s_r-s_{r-k})\ge 0\)。为了好判断合法,我们直接记录\((a,b)\)表示\(s_r-\min,s_r-s_{r-k}\)变化就是\(a\pm 1, b\pm 2\text{或}b+0\)。那么我们就得到了\(O(nq)\)的做法。我们现在相当于是要对所有的中位数都求。我们就把他放到一起求。具体的,从左到右枚举\(r\),维护一个线段树,叶子节点\(i\)存的就是\(x=i\)时当前\(r\),对应的\((a,b)\)是多少。对\(x\)分讨一下,维护变化就行了。然后呢?我们需要知道有多少位置是合法的,也就是\(\ge 0\)的。这个还需要性质。就是发现当\(x\)越来越大的时候,序列中的\(-1\)是越来越多的。所以\(b\)肯定是单调的。但是\(a\)呢?我们关注操作有什么?给一个前缀\(+1\),剩下的后缀\(-1\),在每个位置时需要给\(\ge 0\)的部分\(-1\),一开始肯定时非严格单减的,操作前两个操作的时候还是单减的,然后操作第三个操作的时候,因为给所有\(\ge 0\)的都\(-1\),所以还是保证了单减,所以\(a\)也是单减的,所以\(\max(a,b)\)也是单减的,所以我们相当于是一个前缀和合法的,给一个前缀\(-1\)就行了。得知了\((r,x)\)表示\(r\)\(1\sim x\)时是合法的,剩下写一个二维偏序就行了。但现在还有一个问题。因为现在的操作有三个。1. (a+k,b) 2. (a,b+k) 3. (max(a,b),b)。都是区间操作。这个怎么维护。牛逼的是,大部分的线段树上打\(tag\),都可以写个一个矩阵的形式。例如打区间加的操作。原序列是\([sum,i]\),要\(+k\)。那么就可以写成:

\[\begin{bmatrix} sum & 1 \end{bmatrix} \times \begin{bmatrix} 1 & 0\\ k & 1 \end{bmatrix} \]

区间乘也同理。使用\(\times +\)操作就行。
对应这道题呢?由于有一个\(\max\),操作,所以我们可以使用\(+ \max\)操作

\[\begin{bmatrix} a & b\\ \end{bmatrix} \oplus \begin{bmatrix} k & -\infty \\ -\infty & 0 \end{bmatrix} \]

\(2\)操作同理。\(3\)操作就把\(a[1][1],a[2][1]\)都改成\(0\)就行了。当然我们也可以支持\((max(a+k1,b+k2),b+k3)\),这个就类比就行了。那么我们就可以维护了。

总结:1. 中位数的维护方式。2. \(tag\)可以写成矩阵。3. 当多个限制的操作类似的时候,我们可以把所有操作放到一起维护。

注意:当进行\((a-1)\)这个操作的时候,不能够立刻取\(max\),因为这个东西是对应下一个\(r\)\(a\),但是此时的\(b\)是当前位置的\(b\),所以直接取\(\max\)会出现问题。

CF1983E I Love Balls

就是根据非特殊球来说。因为非特殊球是轮流取得,所以这个期望很好求。考虑非特殊球。因为非特殊球放到那两个球之间的概率是和这两个球之间原本有多少球有关系的,但是期望下,非特殊球之间的球数是一定的,所以期望下概率相等,也就能够直接求了。

总结:期望下的概率反应了所有情况下概率的和,如果所有情况下权值相同,概率就可加,期望概率就有效。

CF1418E

对单个进行考虑。这个就是前\(a\)\(\ge b\)的盾前边不受伤害,后面受伤害,求后面和的期望。首先对于所有\(\ge b\)的盾期望是好求得。然后考虑剩下的点,这个就把所有\(\ge b\)的点看作板,然后每个点向板之间放,就和上面一样了。注意不能理解成把前\(a\)个看作板子,然后向他们的空里放。因为上一个的推导过程中要求每个空的期望球数相同,但是这个显然不同。另一中理解方法是先不看后面的\(\ge b\),如果直接插,那就可以把前\(a\)个看作板,但是要保证剩下\(\ge b\)的都在\(a\)后面,所以后面填的方案肯定会增加,所以也不能看作是等概率的。剩下的就维护一下就行了

CF908D

这个就直接设\(E(x,y)\)表示有\(x\)\(a\)\(y\)\(ab\),要到达合法的状态期望会增加多少个\(ab\)\(E(x,y),y\ge k = 0\),然后转移就是\(E(x,y)=paE(x+1,y)+pb(x+E(x,y+x))\)。当\(x+y\ge k\)时,转移就变成了\(E(x,y)=paE(x+1,y)+pb*x\)。由于前一个可以无限拓展下去,所以就变成了\(\sum_{i=0}^{\infty}pa^i pb(x+i)\),然后拆一下变成了\(\frac{xpb}{1-pa}+\frac{papb}{(1-pa)^2}\)。推法详见这里然后就没了。

P3644 [APIO2015] 巴邻旁之桥

一个桥的时候就直接把端点都放到一个数组里面,找到一个中位数,然后就算。两个数呢?考虑两个桥的时候,设在\(x,y\),那么在\([x,y]\)左边的,一定走\(x\),在右边的一定走\(y\),如果恰好包含\(x\),就走\(x\)\(y\)同理。包含\([x,y]\)的走那个都一样。包含于\([x,y]\)的,走\(x\)的贡献是,\(2*abs(x-(l+r)/2)\)。所以中点比较小的就用左边的,比较大的用右边的,那么推广一下,就是不在\([x,y]\)里面的,也是这个性质。所以枚举在前面的,和其中位数就行了。

CF702F T-Shirts

这个,把顾客建出平衡树,然后每个物品,直接的想法是把\([c,\infty]\)\(-c\),但是这样可能把中序遍历改变了。发现\([2c,\infty]\)\(-c\)还是\(>c\),所以这部分还是在序列的右边。问题是\([c,2c-1]\)的部分,这些\(-c\)了和\([0,c-1]\)的中序遍历可能会坏。不过这些部分至少都\(/2\)了,所以就把他们都取出来,暴力加到平衡树里面,然后就双\(\log\)做了。

总结:关注减去一个值的倍数变化。

P4755 Beautiful Pair

这个题,建出大根堆的笛卡尔树,然后把笛卡尔树拍到序列上,对于一个点,看他左右子树谁的大小更小,在小的树中遍历,用可持久化权值线段树维护一个子树里面的权值,然后就可以查询了。复杂度就是\(O(n\log^2 n)\)的。

CF809D Hitchhiking in the Baltic States

这个比较牛逼吧。暴力就是设\(f_{i,j}\)表示考虑到\(i\),有\(j\)个值,最后一个值的最小值是什么。显然\(f_{i,j}i\)固定的时候\(f_{i,j}\)是严格单增的。转移就是\(f_{i,j+1}=\min(f_{i-1,j+1},L)\),当\(f_{i,j}\in[0,L-1]\)的情况。当\(f_{i,j}\in[L,R-1]\)的时候\(f_{i-1,j}+1\to f_{i,j+1}\)。然后后面的不变。考虑前部分。因为都是小于\(L\)的,所以本来不会变,只会最后一个\(<L\)的位置更新给第一个\(>L\)的位置一个\(L\),所以相当于给\(<L\)后面插入一个\(L\)。插入一个\(L\)后,那么天然的就给后面平移了。那么就需要打一个\(tag\)。但是注意一个细节。就是如果存在\(=R\)\(f\)值。那么不能给后面更新,所以应该把这个值删掉。如果没有,那么第一个\(>R\)的值就会被更新,所以要把第一个\(>R\)的值删掉。那么考虑上面的操作,使用平衡树就能维护了。

总结:dp值不一定只能对应一个数组,也可以是一个数列;考虑\(dp\)的性质和转移的性质,判断用什么维护;用ds维护\(dp\)值感觉很厉害吧。

P4587 [FJOI2016] 神秘数

考虑怎么判断一个区间合法。我们给这个序列排序,从小到大枚举,\(S\)表示\(1\sim i-1\)的和,如果存在一个最小的\(i\)满足\(a_i>S+1\),那么答案就是\(S+1\),否则答案就是所有值的和\(+1\)(糖糖的被不存在的情况卡住了。。)。那么判断一个就是\(O(n\log n)\)的,考虑怎么优化。首先排序可以通过权值线段树优化掉,建主席树就行了。那么跳的过程呢?我们发现,排序后,\(\le S+1\)的是一个前缀,所以我们可以直接把所有\(\le S+1\)加上。这样会跳多少次呢?盲猜\(O(\log v)\)次。怎么证呢?发现\(\le S+1\)的数并且还没加的数可能很少,但是如果有一个\(>S+1\)的,那么\(S\)会翻倍,所以加两次就会翻倍,所以复杂度就是\(O(\log v)\)

总结:\(mex\),能够表示出序列中所有的数,这两个问题都可以通过排序后判断前缀和和当前值的关系转化。给一个值加的东西,考虑是否会翻倍。

P4169 [Violet] 天使玩偶/SJY摆棋子

这个加上一维\(cdq\)分治就行了。注意卡常,如果一个区间全不是询问,那么就不做了。有奇效

P7561 [JOISC 2021] 道路の建設案 (Road Construction) (Day2)

赛时想到正解但是没时间写了。nb吗。就是,考虑\(y=0\)怎么做。把\(x\)排序,找到每个\(x\),左边最近的值,把这些值放到堆里面,每次取出堆顶,把他弹出,找左边的稍微大一点的值,然后再放到堆里面,\(O(n\log n)\)。这很有启发意义把。先对\(y\)离散化一下。如果\(y\)相等,按照\(x\)排序,这样保证了不重。然后按照\(x\)排序,按照刚刚的思路,找最小的,怎么找呢?如果有一颗\(x_i\)的线段树,里面的所有节点都是由\(\le x\)的点构成的,叶子节点的坐标是\(y\),存的是\((-(x+y),-x+y)\)。那么只需要再\(1\sim y-1,y+1\sim n\)中分别查一下就行了。那么我们建主席树。依旧把最小值放到堆里,然后记录是由那个位置贡献最小值的。当堆中取出这个元素的时候就把,这个位置设成\({inf, inf}\)就行了。啊还要新开一个版本。

总结:打模拟赛尽量早点\(A\)前两道,给后面题留时间。

P14400 [JOISC 2016] 回转寿司 / Sushi

先考虑不是环。我们发现对一个区间\([l,r]\),多次向\(l\)放一个值,在\(r\)取出。有一个性质就是值放的顺序是不重要的,只要集合一样,那么最终的序列是相同的。证明:考虑一个数\(x\)的时候。放数的集合是\(S\)。那么如果存在\(<x\)的数,那么一定会把\(x\)换下去,并且\(S\)的最小值是最终的数,因为不会有值把他替换掉。那么放的顺序不影响下一个位置的放数集合。证毕。这个性质很牛逼把。对于一个区间,我们只需要维护一个放数的小根堆,每次把当前位置的值放到堆里,然后弹出堆顶作为这个位置的值,然后给下一个数继承下去。但是题目中,\([l,r]\)是不固定的。但是我们又发现,操作是可以拆分成多个区间的。所以我们想要把这个区间拆成多个区间。那么就有两个算法了,线段树和分块。但是线段树,似乎无法给儿子节点下放标记,故考虑分块。那么设块长是\(B\),每个块内维护一个大根堆表示这个块里的元素。和一个小根堆表示在左端点放的值。给一个整块加一个\(x\),就更新大根堆就行了。给一个散块呢,就先把小根堆的元素按照刚才的说法把\(a\)更新一下。然后再暴力跑当前的\(x\)。然后就完了。不是序列就拆成两部分求。\(B=\sqrt{n}\)\(O(n\sqrt{n}\log n)\)

总结:序列上的问题,当满足可合并,可分裂,才能考虑线段树和分块。并且线段树要满足能向儿子节点\(pushdown\),分块要满足能够打\(tag\),并且下放复杂度正确。

P2839 [国家集训队] middle

这个,有一个性质就是,把\(\ge x\)的设为\(+1\),否则\(-1\),那么一个序列的中位数\(\ge x\),当且仅当序列的和\(\ge 0\)。发现序列的和随\(x\),单降,所以就可以二分。那么我们需要二分中位数,每个中位数要维护前缀和,查询\([a-1,b-1]\)之间的前缀和最小值,\([c,d]\)中间的最大值。这个怎么办呢?发现中位数增加\(1\),就会有一些位置从\(+1\to -1\),也就是只有一些后缀会\(-2\),所以就用主席树就行了。

注意:当\(a-1=0\)的时候,直接查会爆,所以我们查\([1,b-1]\)的最小值和\(0\)\(\max\),被卡在这好长时间。。。

总结:维护中位数的方法好像只有这种。

P3157 [CQOI2011] 动态逆序对

加一个时间轴三维偏序即可。

P2487 [SDOI2011] 拦截导弹

考虑第一问。朴素的思考就是设\(f_{i}\)表示以\(i\)结尾的下降序列最长是多少。转移就是\(f_{i}=\max_{j=1}^{i-1}(f_j+1)*[h_j\ge h_i,v_j\ge v_i]\)。我们发现转移是类似三维偏序的,\((j,h_j,v_j)\to (i,h_i,v_i)\)当且仅当\(j<i,h_j\ge h_i,v_j\ge v_i\),那么就可以考虑\(cdq\)了。计算概率,我们就需要算出总方案数,然后计算每个位置被包含在最优方案的方案数。总方案数好求,转移的时候加一个\(g_i\)表示最优方案的方案数就行了。记录一个最长的\(f_i\),再反过来求一个最长的长度就行了。类比求\(LDS\),我们可以正着求以\(i\)结尾的\(LDS\),再反过来从后向前求\(LIS\)就行了。然后相加\(-1\)和最长的比较。

总结:如果转移除了\(i\)有限制,还有其他限制,就可以考虑用\(cdq\)优化。

P4248 [AHOI2013] 差异

建出height后,然后单调栈做就行了。

P2408 不同子串个数

就对不同的后缀分别计数,考虑排名为\(i\)的后缀能增加多少,就是这个后缀的长度-\(height_{i}\)。因为\(height_i\)在前面出现过了,剩下的都没出现过。

P4143 采集矿石

这个先说一下怎么求排名。先建出\(SA\)。例如要找\(S(l,r)\)这个的排名。我们先在\(rk_l\)前面找一个第一个\(height_i<r-l+1\)设为\(i\)。考虑这是\(S(l,r)\)第一次出现的\(i\)。那么考虑\(i-1\)前出现的子串,都严格比\(S(l,r)\)小,所以记录一个\(sum_i\)表示\(1\sim i\)排名的后缀的本质不同的子串有多少个。并且\(height_i\)也在前面出现过,所以这个的排名是\(sum_{i-1}+r-l+1-height_i\)。注意到这个题是倒序的。所以用\(sum_n-x+1\)就行了。然后考虑怎么做。发现性质保证了合法的不超过\(1e5\)个。这个是个提示把。我们思考为什么会满足这个性质。因为\(v\)都是非负的,所以对于一个\(l\)\(r\)增加,\(v\)不降。而这个题目的排名定义让排名是严格单降的。。。所以二分就行了。。。。。双\(\log n\)就做完了。

总结:求一个\(S(l,r)\)的排名,可以\(O(n\log n)\)求出;注意题目排名设置,如果感觉和平常的不一样,那么就有点问题了;关注题目里给的限制。

CF1746F Kazaee

就,如果一个\((l,r,k)\)是合法的,那么\(k|sum(l,r)\),这是必要条件。如果只用这个判断就挺不对的,出题人很好就卡掉了。怎么办呢?我们可以给不同的数随意一个权值,那么如果本来就合法,那么现在还合法,如果不合法,因为是随机的,所以不合法变成合法的概率是\(\frac{1}{minp(k)}\)?这个不知道为啥,看讨论区这么说的。不过即使概率很大,我们多随机几遍,概率不就变小了吗(doge)。。。。随机化好难。

P4292 [WC2010] 重建计划

就,对于平均数的处理方法就是二分答案,如何判断\(\frac{\sum}{|S|}\ge mid\),就\(\sum - |S|mid\ge 0\)。这个就比刚才内阁好判断了。然后呢,我们就相当于在树上找一条链使得他总和大于零就行了(边权\(-mid\))。啊还有长度限制。没关系。因为是链的问题,所以考虑点分治,在第一个被遍历到的点上统计,长度限制加一个单调队列就行了。不过这个题也可以长剖,好像更好写一点。

总结:平均数的处理方式要熟练;链上问题可以考虑点分治,长剖。

CF798E Mike and code of a permutation

这个。考虑如果我们按照题目所说的建出来偏序关系的图,那么topo一下就行了。但是偏序关系太多了,如果只建\(i\to j\)代表\(p_i<p_j\),还是很多,考虑优化建图。思考这个\(a\)。当\(a_i=-1\)时,说明\(p_i\)比剩下的所有点的都大。当\(a_i=j\)时,说明\(1\sim j-1\)中剩下的点。所以我们相当于是要维护可以动态删点的集合,并且可以对一个区间连边。那么考虑线段树优化建图。一开始肯定是建全树,然后儿子指向父亲,叶子节点就是\(l\to cur(l)\)。就是\(l\)指向其在线段树上的节点。然后遇到了一个\(a_i=-1\),就把全局指向\(i\),否则\(1\sim a_i-1\)指向\(i\)并且\(i\to a_i\)。怎么删点呢?我们肯定不能在当前的线段树上操作,要不就改变了前面的建图了。所以考虑可持久化,开一个新的版本,然后改变\(a_i\)叶子的连边,具体的,就是递归到\(a_i\)后不在用\(a_i\)连向这个线段树上\(a_i\)对应的点。这样相当于是在这个版本后就删掉这个点。然后就做完了。我们也可以反过来,插点,就是把序列反过来,把在最终在没有标记的点连向线段树。然后遇到一个\(a_i!=-1\),就,新开版本连上这条边。

总结:遇到偏序关系可以考虑建图,边数多考虑怎么才能优化建图。

qoj9111

平均数的处理方法。就,设\(f_{i,j}\)表示考虑到\(S\)的第\(i\)位,当前在AC自动机\(j\)节点的最大权值(-\(mid\)版本),记录\(dp_{i,j}\)表示这种情况下不带\(-mid\)是多少,和\(len_{i,j}\)表示长度是多少。答案就用合法的\(f_{n,i}\)\(dp_{n,i},len_{n,i}\)计算答案。

P4707 重返现世

就主要的知识点,就是拓展\(Min-Max\)容斥,还有就是设一个原料第一次出现的时间为\(t_i\),那么一个集合\(A\),出现其中某一个的最早时间的期望值。因为出现一个集合\(A\)的值的概率是\(\frac{\sum p_i}{m}\)。推导一下得到期望时间是\(\frac{m}{\sum p_i}\)。然后我们要找的就是每个元素第一次出现时间的第\(k\)小。因为我们知道上面内阁性质,所以我们找第\(n-k+1\)大,这样\(Min-max\)容斥就能变成求最早时间的期望了。就,式子是\(\sum_{T\subseteq S, |T|\ge k}(-1)^{|T|-k}\binom{|T|-1}{k-1}\frac{m}{\sum_{i\in T}p_i}\)。那么我们求出总和为\(j\)\(T\)对应的容斥系数总和。于是我们设\(f_{i,j}\)表示考虑到\(i\),总和为\(j\)的容斥系数总和。不选很好。直接继承。选,要从\(f_{i-1,j-p_i}\)继承过来,前面的\(-1\)是好维护的,乘\(-1\),但是此时\(|T|\)\(1\)了,所以后面的组合数有问题。我们知道\(\binom{x+1}{y}=\binom{x}{y}+\binom{x}{y-1}\)。那么第一项,就是\(-f_{i-1,j-p_i}\)。后一项呢,我们能看出,内个其实是\(k-1\)时的\(f_{i-1,j-p_i}\)。所以我们在设一维\(f_{k,i,j}\)表示要找第\(k\)大的情况下的容斥系数总和。那么转移就是\(f_{k,i,j}\leftarrow f_{k,i-1,j},f_{k,i,j}\leftarrow f_{k-1,i-1,j-p_i}-f_{k,i-1,j-p_i}\)。至于初始化。。。还不太理解(因为太摆了。)好像把\(f_{0,0,0}=1\)就行了(逃)

总结:像这个。集齐\(k\)个的期望时间,都可以记录其第一次出现的,然后找整个集合的第\(k\)小。然后就可以转化\(Min-Max\)容斥。组合数有一维变化,可以通过递推公式拆分一下就行了。

P3327 [SDOI2015] 约数个数和

就是对\(d(ij)\)的处理。我们把\(x|(ij)\)这个质数分成两部分。就他的唯一分解是\(\prod_k p_k^{c_k}\)。然后\(i=\prod_k p_k^{a_k},j=\prod_k p_k^{b_k}\),把这些质因数分成两部分,1.\(c_k\le a_k\),2.\(c_k>a_k\)。然后前者相乘得到\(d_1\),后者\(p_k^{c_k-a_k}\)乘起来,得到\(d_2\),那么有\(d_1|i,d_2|j,(d_1,d_2)=1\)。并且这样分解出来和\(x\)是双射。所以我们就可以把\(d(ij)\)写成\(\sum_{x|i}\sum_{y|j}[(x,y)=1]\)。然后就莫反。\(\sum_{i}^n \sum_{j}^m\sum_{x|i}\sum_{y|i}[(x,y)=1]\to \sum_{i}^n \sum_{j}^m\sum_{x|i}\sum_{y|i}\sum_{t|x,t|y}\mu(t)\to \sum_{t}\mu(t)(\sum_{t|x}\lfloor\frac{n}{x}\rfloor)(\sum_{t|y}\lfloor\frac{m}{x}\rfloor)\),然后把后面预处理一下,然后两维整除分块就行了。

AT_abc335_g [ABC335G] Discrete Logarithm Problems

\(a_i\)阶为\(g_1\)\(a_j\)阶为\(g_2\),那么\((a_i^{g_1})^{k}=(a_i^{k})^{g_1}=a_j^{g_1}\)。所以\(g_2|g_1\)。然后就求阶,然后暴力判就行了,因为\(P\le 10^{13}\)约数个数\(\le 1e4\),所以就直接跑暴力就行了。求阶。我们能知道所有的\(a_x\),\(ord|x\)。证明就是\(a^{kord+r}\equiv 1\),那么\(a^r=1,r<ord\),只有当\(0\)的时候不与定义冲突

CF1106F Lunar New Year and a Recursive Sequence

求原根,\((998244353)\)的最小原根是\(3\)。然后呢。就取\(\log\)把次幂转成乘法,乘转成加法。那么就可以设\(f_k=3^x\),然后矩阵快速幂求出\(f_n=3^{kx+b}\),然后就能求\(x\)了。求原根就暴力求,就\(i\)\(1\sim N\),判断\(i^{\varphi(P)/p_j}=1\),如果是就不是原根,如果不是就是原根。

P3312 [SDOI2014] 数表

就是式子可以写成\(\sum_{i}\sum_{j}\sigma_0(\gcd(i,j))[\sigma_0(\gcd(i,j))\le a]\)。能知道\(\sigma_0\)是个积性函数,所以这个可以快速求,但是有内个\(\le a\)的限制,导致我们不太好拆\(\sigma_0\)。但是可以枚举\(\gcd\)。那么就是\(\sum_{d}\sigma_0\sum_{i}\sum_{j}[\gcd(i,j)=d]\),后边这个比较经典,\(\sum_{d}\sigma_0(d)\sum_{i}^{n/d}\sum_{j}^{m/d}\sum_{t|i,t|j}\mu(t)\to \sum_{d}\sigma_0(d)\sum_{t}^{n/d}\lfloor\frac{n}{dt}\rfloor\lfloor\frac{m}{dt}\rfloor\)。枚举\(K=dt\)\(\sum_{K}^{n}\lfloor\frac{n}{K}\rfloor\lfloor\frac{m}{K}\rfloor\sum_{d|K}\sigma_0(d)\mu(K/d)\)。设\(g_{n}=\sum_{d|n}\sigma_0(d)\mu(n/d)\),所以前面内个式子只与\(K\)相关。那么对于一个询问,我们就可以\(O(\sqrt{n})\)做了。怎么处理\(a\)的限制,就是把询问离线,按\(a\)排序,然后把\(\sigma_0(d)\)排序,然后动态加点,用树状数组维护一下,复杂度就是\(O(q\sqrt{n}\log{n}+n\log^2{n})\)

P3687 [ZJOI2017] 仙人掌

就首先可以把仙人掌拆成森林做,所以考虑树怎么做。我们考虑,如果最终的图有单个边,那么认为这条边在一个二元环上,那么所有边都在一个简单环上了。然后考虑\(dp\)\(f_u\)表示\(u\)子树的答案。注意这个子树一定会有一个指向\(u\)上面的点,如果儿子里不存在,那么就是\(u\)这个点指向上面。设\(u\)\(x-1\)个儿子,还有一个父亲(\(rt\)先不管)。那么就\(x-1\)里面可以选两个配对,并且可以有的点不选,最多有一个点与\(fa\)配对(这个就是用了每个子树必定有一个指向上面的点)。并且这\(x\)个点每个点至多配对一个点。设这个方案是\(k\),那么答案就是\(k\sum f_v\)。然后发现,这个\(k\)只与\(u\)的度数有关,所以可以预处理,设\(g_i\)表示度数为\(i\)的答案是多少。此时发现就不用\(dp\)了,因为答案就是\(\prod g_{deg_i}\)。考虑\(g_i\)求法。就在相邻点中随便选一个点。那么这个点可以不配对,方案数就是\(g_{i-1}\)。可以配对,方案数就是\((i-1)g_{i-2}\)。那么这个就可以递推了。

总结:像每条边只能存在于一个简单环,不能存在自环的情况,那么孤立边可以直接认为在一个二元环(因为最终的图一定没有重边,所以给这些孤立边加上重边也就没什么问题)。

P125. 池塘

这个。\(check\)可以直接二维前缀和。不需要用线段树。。。。。

P127. 阶乘

这个要注意,\(R\)的范围可以比\(n,m\)小,此时可能答案是\(0\),但也可能\(R\)在分子分母都出现了,导致答案不为\(0\),此时可能会算错。。。阴。。

P3349 [ZJOI2016] 小星星

就,考虑设\(f_{u,i,S}\)表示, 考虑\(u\)子树,\(u\)上的编号为\(i\),子树的编号集合为\(S\)的方案数。转移是\(n^2 3^n\)的,好像可以用子集卷积优化。但是正解不是。当前 考虑 如果编号可以重复选,那么\(f_{u,i,S}\)的定义就变成\(u\)子树的编号集合恰好为\(S\)的方案数。当\(siz_u=|S|\)时,那么编号一定不重。所以答案还是\(\sum_{i}f_{1,i,U}\)。那么有了恰好,所以我们钦定一下。就是设\(g_{u,i,S}\)表示\(u\)中的编号集合属于\(S\)的方案数总和,那么\(g_{u,i,S}=\sum_{T\in S}f_{u,i,T}\)。然后就\(n^3 2^n\)就做完了。

总结:\(n\)比较小的时候,考虑状压;如果答案时恰好,可以考虑钦定成属于或包含,然后再做容斥。

P9352 [JOI 2023 Final] 训猫 / Cat Exercise

这个就是走子树最大值一定是最优的。因为\(dis_{u,v}\le dis_{u,w}+dis_{w,v}\)。然后正着维护也可以,但很麻烦。考虑 如果当前\(n\)点,那么转移就是\(f_{n}\max_{v}(f_{maxv}+dis_{u,maxv})\)。那么枚举\(n\)的出边,枚举到\(v\),设\(v\)所在子树最大的编号为\(x\),那么对\(f_{x}+dis_{u,x}\)\(\max\),然后把这两个连通块合起来。然后重复做,知道做完。考虑如果现在还有一个\(n+1\)节点,那么就找\(n+1\)的出边,然后做就行了。发现这样我们就可以从小到大枚举所有\(i\),然后枚举比他小的出边,在其连通块中更新\(i\)的答案,然后合并。

CF809E Surprise me!

\(\varphi(a_i\times a_j)=\varphi(a_i)\varphi(a_j)\frac{\gcd(a_i,a_j)}{\varphi(\gcd(a_i,a_j)}\)。那么我们对一个\(\gcd=d\)的求。计算\(\sum_{\gcd(a_i,a_j)=d}\varphi(a_i)\varphi(a_j)dis(i,j)\)。然后转化一下,\(\sum_{d|\gcd(a_i,a_j)}\varphi(a_i)\varphi(a_j)dis(i,j)\),设\(g_d\)等于这个。那么设\(f_d\)是恰好,那么\(g_d=\sum_{d|x}f_x\)\(g\)可以建虚树然后就直接做了。

总结:\(\varphi(a_i\times a_j)=\varphi(a_i)\varphi(a_j)\frac{\gcd(a_i,a_j)}{\varphi(\gcd(a_i,a_j)}\)

P16329 bloom

就是 设\(1\)类点是\((\),\(0\)类点是\()\),那么最后会变成\()))(((\)这样。也就是是括号相消的过程。考虑一个\(0\)类点在什么情况下会贡献答案。找到上一个存活的\()\),只考虑右面的\((\),那么把\((\)看作权值为\(+\),\()\)\(-\),所以当前\()\)存活的条件就是这一段的权值和\(<0\)。也就是等价于设\(s_i\)为前缀和,那么\()\)存活的条件就是\(s_i\)严格为前缀最小值。\((\)就是反过来的右括号。那么设\(f_{i,j,k}\)表示填到第\(i\)个位置,总权值和为\(j\),当前与前缀最小值的差值为\(k\)的权值和。当这一位填\((\)\(f_{i,j,k}\leftarrow f_{i-1,j-a_i,k-a_i}\),当这位填\()\)并且不存活,\(f_{i,j,k}\to f_{i-1,j-a_i,k+a_i}\),当前填\()\)并且存活下来,\(f_{i,j,k}\leftarrow f_{i-1,j-a_i,l<a_i}\)。可以前缀和维护。什么对角线啊,三角形啊,什么的。然后把正反两个卷一下就好了。

总结:操作后的权值,考虑对着答案看性质,就是剩下的点的性质(答案不一定是最终答案,可能就是操作后的答案);

P10764 [BalticOI 2024] Wall

设当前方案中,\(i\)的高度为\(h_i\),\(premax_i=\max_{i}(h_i)\),设\(H_i=\min(premax_i,sufmax_i))\),那么贡献就是\(\sum(H_i-h_i)\)。后面一项是好求得,\(\sum(a_i+b_i)2^{n-1}\)。要求就是\(\sum H_i\)。由于定义带着\(\min\)很难受把。转化一下\(\sum_{x}^{+\infty}\sum_{i}[H_i\ge x]\)。经典转化。那么对于一个\(i\),考虑有多少情况\(H_i\ge x\),那么就是\(2^n-(\text{左不行})-(\text{右不行})+(\text{全不行})\)。设\(c_i=[a_i<x]+[b_i<x]\),那么左不行就是\((\prod_{j=1}^{i}c_j)2^{n-i}\)。同理右不行就是\((\prod_j^i c_j)2^{n-i}\)。全不行就是\(\prod c_i\)。那么对\(x\)进行扫描线,每次扫是\(O(1)\)个改变。使用线段树维护这些东西就好了。所以复杂度就是\(O(n\log n)\)了。

总结:\(\sum_{i}H_i=\sum_{x}\sum_{i}[H_i\ge x]\)

#211. 【UER #6】逃跑

这个好难啊。就答案是方差。方差等于\(E(x^2)-E^2(x)\)\(E(x)\)是好求的,就是拆贡献,计算每个位置被遍历到的概率,设\(w_{i,x,y}\)表示第\(i\)步遍历到\((x,y)\)的概率。这个就暴力做就行了。设\(E(x)=d\)。考虑\(E(x^2)\)怎么求。考虑拆贡献,就是\((1+1+1+1+1+1)(1+1+1+1+1+1)\),然后拆成若干个不同的\(1*1\)和相同位置的\(1*1\),就是代表不同的点对配对,和相同的点平方,那么设一个方案不同点两两配对的方案(无序)\(=d_2\),那么\(x^2=2d_2+d\),所以\(E(x^2)=E(2d_2+d)=2E(d_2)+E(d)\),后面内一项已经求出了。考虑求前面内一项。先求一些辅助数组\(g_i\)表示走了\(i\)步,不经过\((0,0)\)的概率,这个就枚举最后一次到\((0,0)\)\(g_i=1-\sum_{j}^i W(j,0,0)g_{i-j}\)。可以递推了。设\(F_{i,x,y}\)表示走到\(i\)步,第\(i\)步第一次走到\(B(a,b)\),并且存在一个点\((a-x,b-y)\)在前\(i\)步中出现的概率和其实就是前\(i\)步中,有多少不同点配对的期望值,(这里配对要求在先遍历到的配对后遍历到了,这样保证了不会重复)。形象化的,就是找第\(j\)步走到\(A\),第\(i\)步走到\(B\),然后\(A,B\)都是第一次经过,并且坐标差为\((x,y)\)的点对的期望和。那么答案就是\(\sum_{i,x,y}F_{i,x,y}\)就对了。然后求\(F_{i,x,y}\)需要容斥。设一些辅助数组,\(S_{i,x,y}\)表示\(i\)步中走到\((x,y)\)并回到\((0,0)\)的概率和,\(R_{i,x,y}\)表示\(i\)步走到\((x,y)\)并且不走到\((0,0)\)的概率。\(R_{i,x,y}=W_{i,x,y}-\sum_{j}W_{j,0,0}R_{i-j,x,y}\),\(S_{i,x,y}=\sum_{j}W_{j,x,y}\)总方案就是\(\sum_{j}g_j W_{i-j,x,y}\)\(g_j\)就是第一次走到一个点。然后会有问题。就是第一种情况是\((0,0)\to A\)的路径上会有\(B\),那么就是\(\sum_{j}g_j S_{i-j,-x,-y}\)。但是这样会多减,就是如果\(g_j\)到达\(B\)之前还有\(A\),那这个方案是合法的,所以不应该减掉,所以\(+\sum_{j}F_{j,x,y}S_{i-j,x,y}\)。第二种是\((0,0)\to A\)没有\(B\),但是第\(i\)步不是第一次到\(B\),就是\(A\to B\)中还有\(B\),所以减去\(\sum_{j}F_{j,x,y}W_{i-j,0,0}\)。然后就没了把。

补:\(d=\sum_{i,x,y}W_{i,x,y}g_{n-i}\)就是枚举最后一次遍历到\((x,y)\)

注意:他这里的方差的权值是\(w_i\)不是概率,所以求出期望和后还要乘\((\sum_{i}w_i)^n\),题目还要乘,那么乘。

总结:拆\(x^2\)可以看作配对,这个转化很妙把。剩下的容斥很有实力 感觉需要写很多题。好题,思维链比较长。

P4336 [SHOI2016] 黑暗前的幻想乡

这个就是矩阵树,啊这个,结论在这里。考虑,如果\(n-1\)个建筑公司都用到,那么就是合法的。但是对一张图跑,不一定都用到了,所以容斥。设\(g_{S}\)表示使用公司集合属于\(S\)的方案数总和,\(f_S\)表示使用公司集合恰好为\(S\)的方案数。\(g_{S}=\sum_{T\subseteq S}f_T,f_{T}=\sum_{S\subseteq T}(-1)^{|T|-|S|}g_S\)。复杂度\(n^3 2^n\)

P5024 [NOIP 2018 提高组] 保卫王国

就动态\(dp\),维护的时候,就是如果强制不选,那么矩阵的第\(1\)列都\(+inf\),强制选就是第\(2\)列。到一个重链的顶部怎么办,直接把链顶到链底的矩阵乘起来就好,在乘\((0,0)\)就好了。这样就能更新出链顶的答案了。发现我们改的都是矩阵,所以可以把两个操作分开做,同理恢复的时候也是,也可以分开做。实现这个实现的有点少了

code

P9338 [JOIST 2023] 合唱 / Chorus

这个有点困难。就 我们把\(A\)看作右走一步,\(B\)看作上走一步。先把所有的点都移到\(y=x\)下方,这个是好做的。然后考虑,我们匹配,相当于是通过平移平移出若干个斜边是\(y=x\)的等腰直角三角形。平移只能由横向上平移和竖向左平移。交换一个\(BA\)的操作次数是\(1\),操作一个\(BBBBAAAAA\)变成\(AAAAABBBBB\)\(A\)数量乘\(B\)数量,这个就是通过平移得到的。还是在折线图上考虑,就考虑最终方案,是若干个等腰直角三角形构成,设其是\(\mathbb{B}\),原图形是\(\mathbb{A}\),那么这个方案的操作次数就是\(B\)存在的但\(A\)不存在的面积。因为\(A\)存在的可以平移到\(B\)上,从外层向里面贴。但里面的就只能通过操作平移到\(B\)上了。所以设\(f_{r,j}\)表示在\(r\)处有结束的三角形有\(k\)个的最小代价。那么\(f_{r,j}=\min_{l=1}^{r-1}f_{l,j-1}+W_{l,r}\)。关注到\(W_{l,r}+W_{l-1,r+1}\ge W_{l,r+1}+W_{l-1,r}\)。也就是并优于包含,满足四边形不等式,\(f_{n}\)关于\(j\)是一个下凸的。所以可以\(wqs\)二分。那么考虑\(f_{r}=\min_{l}f_{l}+W_{l,r}-k\)(\(k\)是二分的斜率)。考虑\(l,r\)怎么求,对列求,设\(g_i\)表示第\(i\)个横的纵坐标是\(g_i\),设\(pos_l\)表示第一个大于\(g_i\)的位置,不难发现\(g_i,pos_i\)都是单调的,\(W_{l,r}=\sum_{i=pos_l}^{r}(g_i-l)\),那么前缀和优化一下\(S_i=\sum_{j=1}^{i} g_j\),就是\(W_{l,r}=S_r-S_{pos_l-1}-l*(r-pos_l+1)\)。那么转移就是\(f_{r}=\min_{l=1,pos_l\le r}^{r}f_{l}+S_r-S_{pos_l-1}-l*(r-pos_l+1)-k\)。然后设\(b_l=f_l-S_{pos_l-1}+l*(pos_l-1)-k\),那么转移就是\(f_{r}=\min_{l=1}^{r}(b_l-l*r)+S_r\),先不看\(S_r\),那么就是\(f_{r}+l*r=b_l\),把\(x=l,y=b_l,k=r,b=f_r\),那么就是斜率单增,求截距的最小值,可以下凸壳优化\(dp\),这样就是\(O(n)\)了,总复杂度就是\(O(n\log n)\)

总结:\(wqs\)的形式分辨;看到一个二元的,考虑有没有四边形不等式;优化\(dp\),存在之和\(j\)有关,只与\(i\)有关,和\(ij\)有关,可以考虑斜率优化什么的;下凸壳;凸性很牛逼啊;

P4451 [国家集训队] 整数的lqp拆分

这个是有序的拆分数,如果系数都是\(1\),那么答案就是\([x^n]\sum_{m=1}^{+\infty}(\sum_{i=1}^{+\infty}(x^i))^m\)。有系数就是\([x^n]\sum_{m=0}^{+\infty}(\sum_{i=1}^{+\infty}(F(i)x^i))^m\),由于斐波那契数列\(F(x)\)的封闭形式是\(\frac{x}{1-x-x^2}\),但是这个没有\(x^0\),不过\(F(0)=0\)也没关系。那么化简一下得到\([x^n]\frac{F(x)}{1-F(x)}=[x^n]\frac{x}{1-2x-x^2}\)。然后做。我们从头捋一下。首先斐波那契数列的封闭性是是怎么来的呢?由于\(f_n=f_{n-1}+f_{n-2}\),所以我们可以把\(F\)右移一位,和右移两位加起来,即\(F(x)=xF(x)+x^2F(x)\)。但是此时发现这样算\(F(1)\)就是\(0\),所以应该补一下,加上一个\(x\),就是\(F(x)=xF(x)+x^2F(x)+x\),然后解一下方程得到\(F(x)=\frac{x}{1-x-x^2}\)。那么怎么通过这个得到通项公式呢?我们发现可以通过\(\frac{C}{1-Ax}\)得到其展开形式的系数是等比数列,所以通项就是\(C*A^n\)。那么考虑\(\frac{x}{1-x-x^2}\),这个分母不是\(1\)次,所以考虑拆一下,设式子等于\(\frac{C}{1-Ax}+\frac{D}{1-Bx}\)。那么得到式子\(AB=-1,A+B=1\),就能求出\(A,B\)了,然后通过\(C(1-Ax)+D(1-Bx)=x\),求出\(C,D\),所以就能写出通项了。然后再看\(\frac{x}{1-2x-x^2}\),这个也可以用这样的方法求出通项,得到通项,就是\(\frac{\sqrt{2}}{4}[(1+\sqrt{2})^n-(1-\sqrt{2})^n]\)。暴力抱一下\(mod\)下谁是\(\sqrt{2}\)就好了,就是跑出来\(i*i\equiv 2\pmod 2\)即可。

生成函数太牛逼了、

qoj7750

。要求最大值的最小值,二分答案。让\(\forall m,(\sum_{i=1}^{m}a_{p_i},\sum_{i=m}^{n}b_{p_i})\times c_{p_m}\le X\),即\((\sum_{i=1}^{m}a_{p_i},\sum_{i=m}^{n}b_{p_i})\le \frac{X}{c_{p_m}}\),(一个整数小于一个小数,所以下取整就行)。一个前缀和一个后缀不太好搞,设\(B=\sum b_i\)。则\(\sum_{i=1}^{m-1}(a_{p_i}-b_{p_i})\le \frac{X}{c_{p_m}}-B-a_{p_m}\),设\(d_i=a_i-b_i,e_i=\frac{X}{c_i}-B-a_i\)。那么就是\(\sum_{i=1}^{m-1}d_{p_i}-e_{p_m}\le 0\)。考虑怎么排列能让\(\max(\sum_{i=1}^{m-1}d_{p_i}-e_{p_m})\)最小。考虑邻项交换法。换\(m,m+1\),设\(A=\sum_{i=1}^{m-1}d_{p_i}\),那么就是比较\(\max(A-e_{p_m},A+d_{p_m}-e_{p_{m+1}}),\max(A-e_{p_{m+1}},A+d_{p_{m+1}-e_{p_m}})\),最终答案最好是换之前比换之后小,所以就按照这个排序。排完就对了。然后证明这个可以邻项交换。不会。aqz说场上写出来跑大样例就行了(doge)。

总结:最小值的最大值考虑二分,然后化简式子,尽可能地把式子写的简洁一点,容易发现性质。

CF1536F Omkar and Akmar

这个,就是阶梯\(Nim\)地拓展。考虑一个位置最多操作次数,如果操作次数是偶数,那么不管,操作次数是奇数就按普通地\(Nim\)游戏做。要对每个节点求。注意到\(k\)很小,所以记录下\(\bmod 2k\)意义下,\([0,2k)\)地值,然后换根就行,这是简单地。

总结:感觉这个每个有最多操作次数地,就挺像阶梯\(Nim\)的?

CF1498F Christmas Game

关注到这个,最终状态,相邻两个不同,空格两边的颜色也不同,所以去掉空格后,还是\(ABABAB\)这样的一个环,所以后手必赢。(doge)。然后就枚举空格,组合数一下。

总结:从答案状态中找性质是一个很常见的做题思路把。

P6021 洪水

动态DP板子。

AT_agc035_f [AGC035F] Two Histograms

怎么去重是个问题。观察(题解)发现,重复只有在\(i\)行,\(j\)列,两种方案是\(i\)选到\(j\)\(j\)选到\(i-1\),和\(i\)选到\(j-1\)\(j\)选到\(i\)这两种情况,所以我们就容斥,枚举有多少个对,然后套组合数就行了。

总结:就是,直接统计不好统计考虑去重,找重复的充要。

CF1477D Nezzar and Hidden Permutations

就是,建出图来,有边就有大小关系限制。然后呢,我们把补图建出来,这样就是没边的有大小关系,有边没有,如果有孤立点就特判一下,这些一定实现同的,因为他和其他的点都大小关系,随便把边方向确定一下就确定这个数了。然后剩下的点,证明他能达到上限。然后考虑一个\(\ge 2\)的连通块。把一个生成树拉出来,如果他能达到最优,也就是\(n\),那么剩下的也行,因为显然限制更强了。然后把数划分成菊花,考虑菊花能不能满足,可以,把中心变成\(1\),然后把叶子填\(2\sim n\),另一种方案中心填\(n\),其他的都是前一种减\(1\)的到。这个就达到上限了。那么就能到达最大值了。怎么找补图的生成树。可以暴力用\(set\)跳,因为一个点最多会跳度数个点,所以复杂度就是对的。详见代码。

总结:最优解考虑更强的限制。构造考虑是否能达到一个更严格的上下界并且证明他。

CF1815E Bosco and Particle

这个,就是假设只有三个\(0,1,2\),那么其循环可以暴力做,在一个循环中,设\(a\)表示\(0\to 1\)的次数,\(b\)表示\(1\to 2\)的次数,然后对每一个\(i\)求出,在全局循环中,设\(f_{i}\)表示\(i\to i-1\)的次数。我们知道全局循环一定是局部循环的倍数(因为全局循环,局部一定会循环),所以\(f_{i-1}:f_{i}=a_i:b_i\),又知道\(2\sum_{i}f_{i}\)。然后考虑怎么求\(f_i\),找最小的一组满足\(f_i\)满足所有的\(a_i,b_i\)的限制就行了。然后怎么找最小,因为太大了,所以不能暴力,所以我们考虑在质因数少考虑质数,就是\(\frac{b_i}{a_i}\),所以必须是\(a_i\)的倍数。在指数上加减就行了。详见代码就行了。我们只需要让\(f_0\)能够整除就行了。

注意:要特判有字符串全是\(1\),和他的最小循环节。

CF1481F AB Tree

就是,最理想就是每层都是相同的,答案就是\(\max dep\)。考虑上界是\(dep+1\)。考虑证明,首先我们知道,最多存在一个深度上面有两种颜色,并且如果这个深度上\(b\)(或\(a\),一样)全在叶子节点上,那么答案就是\(dep+1\)。我们让\(dep\)的一段前缀都是\(a\),一段后缀都是\(b\),然后一层是\(a,b\)。然后设这一层是\(i\),并且有\(x\)\(a\)\(B\)\(b\),下一层一共有\(y\)个节点,如果\(x\le y\),那么就把\(a\)全都放到下一层,把下一层的\(b\)全放到这一层,然后递归处理。如果\(x>y\),那么当前这一层至少有\(x+B-y\)个叶子,因为最多有\(y\)个有儿子。并且\(x+B-y\ge B\),因为\(x>y\),所以\(b\)一定能放到叶子上。考虑怎么判断是否能达到\(dep\)。设\(num_{dep_i}\)表示\(dep=dep_i\)的一共有多少点,得到\(\sum{num_i}=n\),所以最多有\(\sqrt{n}\)个不同的值,所以可以分组背包做就行了,复杂度大概是\(n\sqrt{n}\log n\)

总结:猜上下界。然后证明。

P11363 [NOIP2024] 树的遍历

先考虑\(k=1\)的时,考虑一个点\(u\),和其所连边的既集合,也就是一个以\(u\)为中心的菊花,只考虑这部分,就记录先后关系就好了。第一个被遍历到的边是固定的,然后剩下的部分是走一条链,所以这部分的方案数就是\((deg_u-1)!\)。每一个点的方案数都是固定的,所以答案就是\(\prod{(deg_u-1)}\)。现在考虑一下\(k>1\)的情况。设以第\(i\)个边为起点的方案是\(A_i\),那么要求的就是\(\cup A_i\)。直接求不好求,考虑容斥,求出\(g_S\)表示\(\cap_{i\in S}A_i\),容斥就是\(\sum_{S\subseteq U}(-1)^{|S|+1}g_S\),然后可以把\(-1\)放到外面贡献。考虑一个\(S\)怎么求答案。首先一点,是如果\(S\)不能用一条链覆盖掉的话,那么方案数为\(0\),原因是考虑一个菊花,假设外部有两个钦定的边,\(k_1,k_2\),那么从\(k_1\)开始,遍历完菊花出来的一定是一条链,原因是菊花上的边构成了完全图,而\(dfs\)树是没有横叉边的,所以只能是一条链,所以起点和终点一定是\(k_1,k_2\)构成的。同时我们也得到了这个菊花的方案是\((deg_u-2)!\)。拓展一下,我们设覆盖\(S\)的最小链是\(L\),那么方案数就是\(\prod_{u\subsetneqq L\cup u\text{是L的两个端点}}(deg_u-1)!\prod_{u\subseteq L \cap u\text{不是L的端点}}(deg_u-2)!\)。那么聪明一点就是\(\prod{(deg_u-1)!}\prod_{u\subseteq L \cap u\text{不是L的端点}}(deg_u-1)^{-1}\)。那么设\(c_u=(deg_u-1)^{-1}\)。那么我们就只需要统计链上的(不包含端点)的权值乘容斥系数和就行了。考虑我们怎么统计链的答案。经典做法是放到\(LCA\)处统计。于是我们需要维护每个点\(u\)\(u\)作为一个端点,另一个端点在\(u\)子树里的答案。和\(u\)子树里选两个链进行匹配的答案。具体的,设\(f_{u}\)表示\(u\)是一个链的端点,另一个端点在\(u\)的子树里的答案。枚举\(v\),如果\(u\to v\)是关键边,那么有三种方案,1. 选\(u\to v\)这条链,那么答案就是\(-1\),(因为贡献不在端点产生)。2. 选\(u\to v\)这条链,并且\(v\)子树里还有,贡献就是\(-c_v\times f_v\)。3. 不选\(u\to v\),在\(v\)子树里有链,贡献就是\(c_v\times f_v\)。注意,只有\(1,2\)操作是可以贡献到最终答案里的,因为要保证链是最短的。如果\(u\to v\)不是关键边,那么只有刚刚的第\(3\)种转移,并且贡献不到最终答案。考虑在\(u\)合并的方案。也就是匹配子树的方案。设\(half_v\)表示,\(u\to v\)中的一个子树的链的答案。也就是如果\(u\to v\)是关键边,答案就是\(half_v=-1-c_v\times f_v+c_v\times f_v\),如果不是就是\(half_{v}=c_v\times f_v\)。答案就是枚举\(\sum_{v_1,v_2,v_1\ne v_2}c_u\times half_{v_1}\times half_{v_2}\),这个可以用前缀和优化一下就行。

总结:求并可以转化成容斥求交。

P1084 [NOIP 2012 提高组] 疫情控制

这个,贪心的想,就是向上跳比较优。并且这个还是最大值的最小值,所以二分一个答案。对每一个点都倍增跳到能跳到最高的地方,如果能跳到根,就先不跳到根,现在一个儿子先呆着,然后再贪心的进行分配,这部分看代码就好了。

总结:最大值的最小值考虑二分。

CF889E Mod Mod Mod

考虑只有两个的情况\(a_1>a_2\)。考虑把\(a_1\)\(a_2\)划分成若干段。\(a_1=k a_1+r\),那么最多只有两种方案,一个是取\([k*a_1,a_1)\)中的一个数,然后相当于把\(a_2\)变成\(r\),找最优方案,这种情况下就是\(r-1\)。另一种方案,就是放弃最后一个段,然后再最后一个整段找一个数,然后问题就是变成了\(a_2\)中选一个数,也就是\(a_2-1\)。那么我们倒着转移。设\(f_i\)表示在第\(i\)个开始,\(i\)\([0,a_i)\)中取值,得到的最大贡献是什么(最大贡献有点不一样,等会在说)。那么我们找到\(i\)后面第一个\(<a_i\)的位置\(j\),然后分段,然后分两种情况,第二种情况就是直接转移。第一种情况,我们\(dfs\)来处理,就是设\(dfs(i,x)\)表示第\(i\)个值在\([0,x)\)中取值,最大贡献是多少。由于两种情况中只有一个会产生\(dfs\),并且\(x\)还会经历取模,经典结论是取模至多会进行\(\log V\)次,(因为我们会找比\(x\)小的数)。所以\(dfs\)最多会进行\(\log V\)次。所以复杂度是对的。然后考虑最大贡献怎么定义。我们计算最后的答案怎么计算呢。设\(b_i\)表示最优方案中每个位置的值,答案就是\(\sum{b_i}\)。由于要取模,所以是不增的,我们设\(c_i=b_i-b_{i+1}\)。那么贡献可以写成\(\sum_{i*c_i}\)。所以\(f_i\)的最大贡献定义就是考虑\(>i\)\(c_i\)最大的贡献是多少。具体怎么转移。如果取分段后的散段,那么贡献就是\(f_{i}=dfs(j,a_i%a_j)+(\lfloor\frac{a_i}{a_j}\rfloor\times a_j)\times(j-1)\)。就是取上面那一段,那么差值就是\(\lfloor\frac{a_i}{a_j}\rfloor\times a_j\)。肯定能够取到。如果取最后一个整段,那么转移就是\(f_{i}=f_j+(\lfloor\frac{a_i}{a_j}-1)\times a_j\times(j-1)\),原理和上面那个类似。然后有点细节不赘述

总结:取模最多有\(\log n\)个不同的值。对一个单调的序列求和的可以差分。

QOJ17427 Penguin Flicker

期望好题。就是首先,题意可以转化成,在数轴上一些点,然后每次可以把一个点挪到左边点的旁边,或右边点的旁边,或者是第一个或第\(n\)个,还有删掉。因为是弄到旁边,所以我们转化一下,让\(a_i-i\),这样就是和旁边的放到一起。然后要知道\(|x-y|\)的期望,拆一下贡献,计算一个\((i-1,i)\)这个期望被经历过的多少次。我们发现这个只与他左边右边有多少数有关。那么设\(f_{i,j}\)表示一共有\(i\)个数,左边有\(j\)个,然后中间的边期望经过了多少次。我们发现,能够改变状态的只有四种状态,就是第一个删掉,最后一个删掉,左边最右边的挪到右边,右边第一个挪到左边。其他的操作不会对状态产生影响,所以我们可以看作只有这四种操作,并且操作是等概率的,所以转移就是\(f_{i,j}=\frac{1}{4}(f_{i-1,j-1}+f_{i-1,j}+(f_{i,j-1}+1)+(f_{i,j+1}+1))\)。特殊的是\(j=0,j=i\)的情况,我们发现此时特殊操作只有两种,容易推得,\(f_{i,0}=f_{i-1,0}+\frac{1}{2},f_{i,i}=f_{i-1,i-1}+\frac{1}{2}\)\(i\)从小到大枚举,那么\(f_{i}\)层的转移就是一个环,设\(f_{i,1}\)为主元解方程就行了。但是此时还是少考虑贡献了。就是把他删掉的贡献。就是我们的转化后的操作是把一个数重叠到另一个数上,但是删掉在原操作中就是和\(0,L+1\)重叠,如果操作后还是让他重叠,那么在原操作就是\(0,L+1\)旁边连续堆了好多数。计算这部分的贡献,设与\(0\)重叠的有\(i\)个,和\(L+1\)重叠的有\(n-i\)个,操作现在只有把他重叠到\(0,L+1\),其他操作我们不关心,所以一次操作把一个数移到\(0,L+1\)的概率都是\(\frac{1}{2}\),所以贡献就是\(\sum_{i=0}^{n}\binom{n}{i}(\frac{i(i+1)}{2}+\frac{(n-i)(n-i+1)}{2})(\frac{1}{2})^n\)。设\(g_n\)是这个,那么我们就可以\(O(n^2+Tn)\)算答案了。

总结:期望题,先考虑能不能拆贡献;移到旁边什么的,可以通过\(-i\)变成移到上面;如果一些操作不会改变状态,那么就可以不考虑这些操作,而只关注会改变状态得操作,证明可以通过解方程知道,或者理解为我们只关心改变操作的分布,遇到不改变的操作跳过就行了。

P3288 [SCOI2014] 方伯伯运椰子

先是平均数的经典处理方法。然后建新图,如果\(u\to v\)扩容,那么建一条\(u\to v\),权值为\(b_i+d_i+mid\)的边,如果压缩,建\(v\to u\),权值为\(a_i-d_i+mid\)的边,然后找是否存在负环就行了。如果找到负环,说明可以找到一些边增加一些边减少,然后总花费减小,感性上感觉挺对的。就是环上,如果相邻两个边在原图上有同样的起点,那么就相当于给一个边增加一个边减少。然后总流量不变。细节就是\(c_i=0\)不能建反边。

P13356 [GDCPC 2024] 图

关注到$k=\lceil\frac{m}{n-1}\rceil \(。\)n-1\(这个比较关键。如果我们找到\)k\(颗不交的生成树,那么肯定能找到答案。但是显然可能不一定能找到生成树。我们考虑,先找出一颗生成树,把这些边删掉,继续生成生成树, 只能生成森林就生成森林。发现,第\)i\(次生成的生成森林中,若有一条边是\)u\to v$,那么在\(1\sim i-1\)这些森林中,\(u,v\)一定是联通的,否则就会在之前被连上。那么维护\(k\)个生成树。对于一条边\(u\to v\),二分到第一个\(u, v\)不连通的生成树。根据刚才的说明,这个是具有二分性的。剩下的就使用并查集维护就行了。找路径,就找第\(k\)个生成树的一条边\(u\to v\),在前面\(dfs\)找路就行了。

总结:题目中出现了\(n-1\)这个东西,或\(n\)这个东西,考虑和特殊的图有什么关系。

qoj2562 Fake Plastic Trees 2

就。暴力,就设\(f_{u,i,k}\)表示\(u\)子树里分出了\(i\)个连通块,\(u\)所在连通块大小是\(k\),是否可行。然后我们考虑,怎么降低状态。如果有一个\(f_{u,i,x/y/z}\)并且\(x<y<z\),并且\(z-x<R-L\),如果合并过程中\(y\),那么\(x,z\)之中至少有一个可以选,所以\(y\),就没用了,那么状态就是\(\frac{V}{R-L}\),但是还是太大。不过因为\(k\in [V-iR,V-iL]\),所以状态就是\(O(i)\)的。这样就可以做了。我们用\(set\)维护\(f_{u,i}\)可行的\(k\),然后合并,合并两个背包的复杂度就是\(O(k^2\log k)\)。树上背包的复杂度是\(O(nk)\),所以最终复杂度是\(O(nk^3\log k)\)可过。

总结:暴力状态太多,考虑通过必要性限制状态数。

CF1693E Outermost Maximums

转化题意是,每次把当前最大值换成前缀次大值和后缀次大值的较小值。考虑怎么维护这个东西。不知道是怎么想到的(看题解就想到了:hdkk发言),考虑当前最大值集合是\(S\),对于其中的每一个值维护三种符号\(\leftarrow,\rightarrow,?\),分别表示这个值左边有次小值,右边有次小值,左右都没有次小值。枚举全集中下一个最大值\(x\),那么就是给一个前缀打上\(\rightarrow\),给一个后缀打上\(\leftarrow\)。如果一个点上有两种箭头,那么说明我们找到了较小值,所以操作一次把这个点改成\(x\)就可以了。也就是把他的标记打成\(?\)。改成当前值了以后就左右都没有次大值了。由于操作的特性,\(\rightarrow\)是一段前缀,\(\leftarrow\)是一段后缀,\(?\)是中间的一段区间。所以维护就好维护了。

总结:对题意进行转化;按照一定的顺序加入值或考虑问题。

sez156

就是,如果选的集合是确定的,那么判断这个集合合不合法就是按\(e\)排序,两两结合,可以就可以,不可以就不可以。所以\(dp\)这个序列就行了。优化一下就行了。

sez158

考虑给定一个\(k\)容量,问多少数量满足,考虑一个点\(i\),找这个点颜色上一个出现的位置,\(f_i\)\(f_i\sim i\)这之间出现\(\le k\)个颜色就是可以的设颜色是\(cnt_i\)。所以对于一个\(1\)询问\(l,r,k\),我们只需要找\(f_i\ge l,i\le r, cnt_i\le k\)。这个三维偏序就行了。第二问,通过整体二分就能解决,所以就是\(O(n\log^2 n)\)

总结:找性质。就是看要找的答案的充要条件是什么。

P10747 [SEERC 2020] Neo-Robin Hood

int4399秒猜到结论。就是对于两个人\(i,j\)来说,我们选择一个人偷,一个人消除仇恨,如果,偷\(i\)更优,那么有结论\(m_i-p_j>m_j-p_i\to m_i+p_i>m_j+p_j\)。所以按照\(m_i+p_i\)排序,那么一定是一个前缀是偷的全集,后缀是消仇恨的全集。答案显然是具有二分性的。所以二分一个\(k\),然后枚举一个前缀后缀,前缀找前\(k\)大的\(m\),后缀找前\(k\)小的\(p\),然后寻找有没有一个\(\ge 0\)的解。

总结:每个人只能有一种方案,所以,我们考虑给方案配对,然后考虑把配对反过来是否更优。邻项交换nb

P6029 [JSOI2010] 旅行

感觉有点生硬。做法是枚举一个\(x\)表示最优路径上有\(\le x\)条前\(x\)小条边的边。设\(f_{u,j,t}\)表示当前在\(u\),路径上本来就有\(j\)条前\(x\)小中的边,把路径上\(t\)条边替换为前\(x\)条边中的边,那么要求\(j+t\le x, t\le k\)。称前\(x\)小的边为关键边。通过\(dij\)进行转移。当前边是\(u\to v\),如果是关键边并且\(j+t+1\le x\),\(f_{u,j,t}\to f_{v,j+1,t}\),如果不是关键边并且\(j+t+1\le x, t< k\)此时可以替换一条边\(f_{u,j,t}\to f_{v,j,t+1}\)。如果不是关键边,并且选择不替换,\(f_{u,j,t} + w_{u\to v}\to f_{v,j,t}\)。然后就做完了。复杂度是\(O(nmk^4\log(mk^2))\)跑的飞快啊也是.

总结:替换的,可以先枚举替换多少,然后把答案延后贡献,这样转移的时候就可以不关注替换的具体顺序,只需要关注替换的多少条边即可。

P6000 [CEOI 2016] match

做法是,考虑当前处理到区间\(l,r\),那么\(l\)肯定是左括号,我们贪心的想就是让这个左括号匹配的右括号尽可能地靠右。设匹配的位置是\(mid\),那么\(l+1,mid-1\)就一定是可以成为一个合法括号序列地。怎么判断是否是合法括号序列呢?暴力地想法就是,维护一个栈,如果加元素地时候和栈顶相同,那么就弹出,否则就加入栈。如果最终栈空了那么就可以变成合法括号序列。但是这样是单次\(O(n)\)地。不过我们可以维护\(Hash\)值。就是\(i=1\sim n\)一次加入,然后维护一个\(h_i\)表示\(i\)此时栈地\(Hash\)值,如果\(l\sim r\)是合法的,那么答案就是\(h_{l-1}=h_r\),那么这样就可以\(O(1)\)判定了。(和前缀和还挺像的)。那么我们通过二分,就能找到\(mid\)了(注意二分要先保证这两个字符是相同的)。找到后递归\((l+1,mid-1),(mid+1,r)\)。复杂度是\(O(n\log n)\)的就行了。

sez161

数位\(dp\)。比较好的想法是只记录\(a\le b\le c\)的数量,最终再乘方案数。这样的好处是只需要让\(a+b>c\)就行了。然后就记录\(f[i][a<b][b<c][c<s][a\oplus b\oplus c < l][(a>>idx)+(b>>idx)-(c>>idx)]\)注意到最后一维可能很大。但是当其\(>1\)时以后最坏情况也不会小于\(0\),如果\(<-2\),最好情况也不会大于\(0\)。所以状态只需要设\(-2,-1,0,1\)即可。这样就行了。

sez162

关键性质时\(l+r=k\)的所有状态的先手胜败态是相同的。

  1. \(l,r\)先手必败。则\((l-1,r),(l,r+1)\)是先手必胜,所以\((l-1,r+1)\)先手必败。
  2. \(l,r\)先手必胜。则(l,r-1),(l+1,r)\(必定存在一个先手必败。设是\)l,r-1\(。那么\)(l-1,r)\(是先手必败。所以\)(l-1,r+1)$是先手必胜。

证毕。

那么就明了了。找到最小的\(d\),满足\(1+d+1,n-d-1\)是终止状态。考察\(1+d,n-d\)的答案。此时,操作只能拓展一个端点,例如拓展到\(1+d+k,n-d\)\(1+d,n-d-k\)。这样。因为向另一方拓展必败。那么看\(k\)的奇偶性就行了。

上述两个操作都可以二分得到。

P16160 [ICPC 2016 NAIPC] Jewel Thief

暴力是\(O(nk)\)的。题目给的体积都很小。对相同体积的同时考虑,设\(dp_{i,j}\)表示考虑了\(1\sim i\)体积的物品,体积和是\(j\)的最优方案是什么。贪心的想,相同体积的肯定拿价值更大的。于是对于每个体积按价值从大到小排序。设\(a_{i,j}\)表示体积为\(i\)的物品,前\(j\)大的值和是多少。\(a_i\)显然是凸的。设\(g=a_i\)。那么转移就是\(dp_{i,j}=\min_{k=0}^{\frac{j}{i}} (dp_{i,j-k*i}+g_{k})\)。因为选的都是\(ki\),所以在模意义下考虑。\(dp'_{i,j}=\min_{k=0}^j (dp_{i,k}+g_{j-k})\)。由于\(g\)是凸的,所以可以用决策单调性优化了。复杂度\(O(n\log n+sk\log n)\)

总结:如果体积比较小,完全背包可以考虑同余之类的。\(01\)背包可以考虑把相同的放到一起,然后使用决策单调性。

CF1153F Serval and Bonus Problem

\(l\)没啥用,当成\(1\)算了。那么第一个性质是一个区间的长度的期望值是\(\frac{1}{2n+1}\)。考虑对于每个区间考虑有多少区间覆盖这个区间。考虑第\(i\)个区间。如果\(1\sim i\)个点有\(j\)个未匹配的左端点,那么就有\(j\)个区间覆盖他。于是设\(f_{i,j}\)表示考虑了\(1\sim i\)这些点的左右端点分配的方式,还有\(j\)个左端点没有确定的方案数。那么转移就是\(f_{i,j}\to f_{i+1,j+1},f_{i,j} * j\to f_{i+1,j-1}\)。第二个就是枚举和那个匹配。然后合并呢。就是\(f_{i,j}*f_{2*n-i,j}*j!\)。阶乘就是枚举怎么匹配。然后除以总方案数就行了。

总结:两个性质都比较经典的。

CF2107F2 Cycling (Hard Version)

贪心找一些性质。考虑如果当前位于\(i\)是严格前缀最小值,那么最优的操作是每次跳过\(i\)后,把\(i\)\(i-1\)交换,也就是每次花费\(a_i+1\)这个样子。如果当前不是严格前缀最小值,那么考虑找到\(1\sim i-1\)的严格最小值\(j\)。这时候有两种方案。

  1. \(j\)换到\(i\)来,然后每次跳\(j\),要提前花费\(i-j\)的代价。
  2. 先想办法走到\(j\)后面,也就是求出\([j,i]\)的最优方案,在从\(j\)向前走,利用已经求出的信息。

由于有第\(2\)种操作的存在,我们一开始想区间\(dp\)的。但是太爆了。考虑是怎么求\([j,i]\)的最优方案的。操作和整段区间是一样的。并且一直递归做,最终\(i\)一定会成为严格最小值的。所以第一个操作可以写成枚举一个\(j\),把\(j\)换到\(i\)然后跳。第二个操作就是先从\(i\)跳到\(j\),每次使用\(a_i+1\)。那么设\(f_i\)表示\(i\)的答案。可得转移:

\[f_{i}=\min_{j=0}^{i}(f_{j}+(i-j)*(a_j+2), f_j+(i-j)*(a_i+1)-1) \]

然后使用李超斜率优化即可。

总结:找性质。

CF2125F Timofey and Docker

关键的性质是,\(docker\)\(border\)\(0\),所以不会出现两个重叠的情况。所以我们就相当于把原串分成若干段。每段的贡献是在其中改出恰好一个\(docker\)的代价。设\(A_{i,j}\)表示把\([i,j]\)改出恰好一个\(docker\)的代价,\(f_{i,j}\)表示把\(1\sim i\)中分出\(j\)\(docker\)的代价。那么转移就是$f_{i,j}=\min_{k=1}^{i-1} f_{k,j-1}+A_{k+1,i} \(。\)A\(满足四边形不等式。所以答案关于段数是凸的。于是可以\)wqs\(二分了。但是我们还要求\)A\(,这个有点烦。我们改一下\)dp\(。在\)docker\(出现的结尾进行计算。就是\)f_{i,j}=\min{f_{i-1,j},f_{i-6,j-1}+c_i} \(其中\)c_i\(表示把\)i-5\sim i\(这些数改成\)docker\(的最小代价。那么这样就好\)dp\(了。直接改成\)f_{i}=\min(f_{i-1},f_{i-6}+c_i)$。

还有问题是,最优方案对应的段数可能很多。不过因为最终是凸的,还知道串原本就有的\(docker\)数量对应的代价是\(0\),所以找左右两边离他最近的就行了。

第二个问题是。刚才的\(dp\),由于有\(f_{i-1}\)这个转移,所以如果一段区间本来就是\(docker\),当斜率为负时,可能就把这个东西漏算了。所以我们只去二分斜率为正的部分,由于\(-mid\),如果本来就是一个\(docker\),那么一定会被这个选择覆盖了。而斜率为负的部分,我们可以\(O(1)\)算的。

总结:能把暴力\(dp\)想出来也挺厉害的;然后就是判断转移是否有特殊性质;没有\(border\)这个性质还挺好的。

AT_arc193_b [ARC193B] Broken Wheel

这种确定序列的题目。有两个方向。

  1. 直接找有多少合法的序列。这样的题目一般合法的或者不合法的序列会有一些性质,可以通过容斥计数解决。
  2. 枚举序列,判断该序列合不合法。这样的题目状态都可以压进去,或者在转移的过程,只关心\(O(1)\)项状态。

这个题属于第二类。考虑判定一个序列合不合法。设\(dp_{i,0/1,0/1}\)表示考虑到\(0\sim i\)这些边了,\(0\to n-1\)的方向是什么,\(i\to i+1\)的方向是什么,\((u\to v\)\(0)\)。然后对\(s_{i+1}\)\(0/1\),当前度数是多少进行分讨转移。关注到我们只需要知道\(i\)\(00,01,10,11\)的值是多少,\(d_{i+1}\)是多少就能转移了。所以考虑\(dp\; of\; dp\)。设\(f_{i,T}\)表示\(i\)时,\(dp_{i,0/1,0/1}\)的四个值是\(T\)的序列数有多少。然后转移就好了。复杂度\(O(n)\)

总结:确定序列的,在判定过程卓,如果转移之和上一维有关,并且状态数比较少,那么可以考虑\(dp\; of\; dp\)

CF1422E Minlexes

脑子题,我没有脑子。就暴力就是设\(f_{i}\)表示\(i\)后缀最小的是什么。如果\(s_i!=s_{i+1}\),那么\(f_{i}=s_{i}+f_{i+1}\),否则\(f_{i}=\min(f_{i+2},s_i+s_i+f_{i+2})\)。但是比较超时了。不过他让我们只保留前\(5\)\(2\),并且上述操作不会对后\(2\)产生影响,所以比较前五就行了。


有点伤心,感觉最近没有自己做出来一些题。感觉有一点似了。到底是怎么想到的。😢


CF2124F2 Appending Permutations (Hard Version)

这个题和Two Histograms,清仓甩卖很像。就是判定有多少种本质不同的序列。大体方向可以思考什么情况下会重复,在会重复的操作种只选定一种操作进行,强制其他的不进行来保证不会重复。例如这道题。发现重复的是\(1,...r,r+1,...s,1,...r\)。这样就有两种匹配方式了。我们只允许\(1,...s,1,..r\)这样的匹配出现。具体的,如果当前要新开一个段,其开头是\(r+1\),那么他前面的内个段不能同时满足开头是\(1\),并且填到了\(r\)。所以设\(f_{i,j,k}\)表示,第\(i\)个位置,填的是\(j\),本段开头是\(k\)的方案数。转移分讨一下。注意转移时的限制。特殊的说一下\(f_{i,j,k}\leftarrow f_{i-1,j-1,k}\),这个就是直接再后面接一个数,所以不能让\(j=k\)。考虑这个转移其实就是把\(f_{i-1,k}\)向右平移了一下。然后把\(j=k\)的部分删掉,这个转移可以通过移动数组的起点实现。详细见代码把都是细节。

qo5089 环覆盖

一个多项式的更神奇的应用。题意可以转化为每个点的度数都是偶数。当不需要求每个\(k\)的方案时。总的方案就可以写成\([x^{\emptyset}]\prod (1+x^{u_i,v_i})\)。如果需要求每个的方案数,我们就再加一个占位符变成\([x^{\emptyset}]\prod (1+yx^{u_i,v_i})\)。这样\([x^{\emptyset}]\)就是一个多项式了,而\([y_i]\)就代表了\(i\)的答案。有点神奇。并且已知这个多项式是\(m\)次的,所以可以拉插了。考虑怎么对于\(y\)求点值。肯定与\(FWT\)有关的。考虑正变换。由于每一项只有\(y\),所以\([x^S]\prod FWT(1+yx^{u_i,v_i})\)。就一定是\((1+y)^a(1-y)^{m-a}\)。这个我们只需要统计出来有多少边只有一个点在\(S\)中即可。这样直接IFWT还是不行。但是我们只关注\(x^{\emptyset}\)。根据IFWT定义,就是$\frac{\sum [xS]}{2n} \(。所以对\)a\(统计有多少\)S\(对应\)(1+y)a(1-y)\(的。就可以\)O(2n+m2)$求了。

总结:多项式新的用途;做题的时候,关注要维护的信息,当维护的信息比较特殊时,可以用特殊或更简洁的方法解决,如维护和,\(0\)次项系数等等。

P5206 [WC2019] 数树

先特判\(y=1\)的所有情况

前置知识是\(prufer\)序列应用,即为什么生成树是\(n^{n-2}\),以及包含\(k\)个连通块,每个连通块大小为\(a_i\)的生成树的个数是\(n^{k-2}\prod a_i\)

\(op=0\)是简单的。答案就是\(y^{n-E_1\cap E_2}\)

\(op=1\)。答案就是\(\sum_{E_2}y^{n-E_1\cap E_2}\)。我们可以考虑钦定交集,然后容斥。考虑一个容斥的式子。$f_{S}=\sum_{T\subseteq S}\sum_{P\subseteq T}(-1)^{|T|-|P|}f_P \(,这个好证,只有当\)P=S$时有值。所以容斥就这么写

\[\sum_{T\subseteq E_1}g(T)\sum_{P\subseteq T} (-1)^{|T|-|P|}y^{n-|P|} \]

。推一下式子得到

\[\sum_{T\subseteq E_1}g(T) y^{n-|T|}\sum_{P\subseteq T}(-y)^{|T|-|P|}\to \sum_{T\subseteq E_1}g(T) y^{n-|T|}(1-y)^{|T|} \]

\(g(T)\)是包含\(T\)的生成树个数。就是\(n^{k-2}\prod a_i,k=n-|T|\),然后就变成了

\[\sum_{T\subseteq E_1}n^{k-2}\prod a_i y^{k}(1-y)^{n-k}\to \\ \frac{(1-y)^n}{n^2} \sum_{T\subseteq E_1} \prod \frac{ny}{1-y}a_i。 \]

\(C=\frac{ny}{1-y}\)。那么就可以看作,在每个连通块中选一个点进行贡献\(C\)(就是把\(Ca_i\)拆成\(a_i\)\(C\)相加),所有方案贡献的总和。于是可以设\(f_{u,0/1}\)表示\(u\)这个连通块有没有选一个点贡献。然后树形dp就行了。

\(op=2\)
类似的能得到一个式子。

\[\frac{(1-y)^n}{n^4}\sum_T \prod_{i=1}^{k}a_i^2 \frac{n^2 y}{1-y} \]

\(C=\frac{n^2 y}{1-y}\)
很神秘的一步来了。枚举\(T\),实际上是划分连通块,所以我们先枚举\(k\)。然后把\(1\sim n\)放到\(k\)个连通块里,类似\(n\)个有标号的点放到\(m\)个无编号的盒子里。一个大小为\(a\)的盒子的贡献是\(Ca_i^2\),还要乘上生成树的方案。就是\(a^{a-2}\),结合一下就是\(Ca^a\)。考虑一个盒子的生成函数是\(\sum_{i=1}^{n}Ci^i x_i\)。那么\(k\)个盒子就是\((\sum_{i=1}^{n}Ci^i x_i)^k\)。因为有编号,所以要写成\(n!(\sum_{i=1}^{n}\frac{Ci^i x_i}{i!})^k\)。盒子没标号,所以\(n!\frac{1}{k!}(\sum_{i=1}^{n}\frac{Ci^i x_i}{i!})^k\)。那么总方案的生成函数就是\(n![x^n]\sum_{k=1}^{+\infty}\frac{1}{k!}(\sum_{i=1}^{n}\frac{Ci^i x_i}{i!})^k\)。设\(F(x)=(\sum_{i=1}^{n}\frac{Ci^i x_i}{i!})\),那么实际上就是\([x^n]n!(e^{F(x)}-1)\)。使用多项式exp就行。

总结:绷。一个式子使用组合意义,例如\(\prod ab\),可以拆成\(a\)\(b\)相加,如果\(b\)是常数的话。计数题可以尝试用生成函数来描述问题。

CF715E Complete the Permutations

这道题的动机是考虑两个排列的距离怎么计算。经典结论是\(p_i\to q_i\)。距离就是\(n-\)环数。考虑这道题。如果直接连边的话,那么会得到四种边。

  1. \(a\to b\)
  2. \(a\to 0\)
  3. \(0\to a\)
  4. \(0\to 0\)
    第一种边,我们就可以把他们看作是一个点。那么最终只会有后三种边。设三个边的个数分别为\(n_1,n_2,m\)。考虑怎么填数使其生成环。考虑操作。合并\(a_1\to 0,a_2\to 0\)。相当于把\(a_1\to 0\)\(0\)换成\(a_2\),然后在合并得到\(a_1\to 0\)。同理\(0\to a_1,0\to a_2\)。这些都是出现过的。还有操作是\(0\to 0,a\to 0\),合并为\(0\to 0\)。相当于把一个\(0\)变成\(a\),然后\(0\to 0\)填没有填过的数字,这是其他的关系。那么对于三个边的操作就比较确定了。
  5. 合成环,或者转化成别的边
  6. 同1
  7. 合成环。

关注操作发现\(1,2\)不能互相转化,\(1,2\)不会使\(3\)数量改变。

考虑\(1\)合成\(k\)条链的方案。就是$F(k)=\sum_{i=k}^{n_1}\binom{n_1}{i}\left[{i\atop k}\right] (n_1+m-i-1)^{\underline{n_1-i}} $。

这个转移的意思就是先枚举合成多少个环。把剩下的\(1\)类边合并成其他的边。第一个\(1\),可以放到其他的\(1\)后面,可以放到\(3\)后面,所以就是\(n_1+m-i-1\),第二个因为少了\(1\)个,所以就是下降幂的形式。

\(2\)同理。

\(3\)。所以这个想成环就成环。所以相当于是\(n\)个点,形成\(k\)个环的方案数,也就是第一类斯特林数。但是第一类斯特林数只是确定了对应关系。但是对应关系可以排列,所以\(F3(k)=m! \left[{m\atop k}\right]\)

接下来就把三个函数卷起来就好了。\(O(n^2)\)。注意考虑一开始有多少环。

总结:两个排列的距离的结论。能想到缩点,但是不知道怎么合并成环了。关注过程中的信息量,这也算性质中的一部分,例如数量不变,总和不变之类的,可能作为特殊性质出现。

P3647 [APIO2014] 连珠线

想了好久。。还是没切。比较开心的是能够想到大体思路。不开心的是,没有往换根的方向想,所以有一些性质没有找到。

看到这个题的一开始,想到判定一张图是否能得到,来反推性质。考虑特殊一点的,所有蓝边形成了一个连通块,然后判断这个连通块是否合法。考虑把这些蓝边都变成一个点,题中的操作让我们能得到一些性质。

  1. 操作过程中不能存在一个点\(u\)\(\ge 3\)个儿子是叶子节点。
  2. 存在\(u\to x\to y\)\(x\)的度数为\(2\)\(y\)的度数为\(1\),那么可以把\(x,y\)删掉。
  3. 存在\(u\to x,u\to y\)\(x,y\)的度数都为\(1\),那么可以把\(x,y\)删掉。

但是这样会出现一些问题。就是能发现,第\(3\)种情况,\(x,y\)其中一个必定是起点,所以如果一个连通块同时出现了两个\(3\),那就炸了。但是这种情况感觉根本不能判掉,尤其我们还要合并几个蓝边的连通块。对,我就是卡在这里了。

考虑怎么解决。我们想要把第\(3\)个情况去掉。又不能删点。但是发现,第\(3\)中情况也可以转成\(2\),就是因为都是\(1\to 2\to 1\),所以可以把\(x\)当根,也就是把起点当根,那么图中只存在\(3\)了。此时我们只需要求出对每个点都当根的最大权值,也就是换根dp就行了。

总结:一个思路想太久思考到底是哪里卡住了,能不能操作使这种情况不出现;

Loj2785

考虑一个\(u\to ls, u\to rs\)。能排列的方式只有\(4\)种,其中\(u,ls\)当根的放置方案是固定的。然后子树就变成子问题了。\(rs\)当根\(u,ls\)就可以交换了。要考虑怎么才是最优的。自然的想法是,设\(f_{u,j}\)表示\(u\)初始为\(j\),他最终在哪里。但是一眼\(O(n^2)\)。好像爆了。

由于操作的性质,一个点最多向上走一次。所以能到这个点的值只有其到根节点的点和他们的左右儿子。也就是\(O(\log n)\)个。这样就能做了。

总结:dp复杂度比较大,除了常规的优化方式,我们可以考虑能不能从状态下手,例如找到某些状态不会用到(好像还挺常用的)。

AT_arc087_d [ARC087F] Squirrel Migration

这个感觉有意思的是,因为每个边的贡献次数是\(min(siz_u,siz_v)\),所以拿重心当根,这样每个点必须和不同子树里连边,就是不在根节点的同一颗子树里。然后容斥,算钦定\(i\)个点在同一个子树里连边,然后这个背包进行解决。

总结:有启发的是重心当根的性质把。

P7520 [省选联考 2021 A 卷] 支配

支配关系不能成环,没有横叉边,形成一颗树的结构。受支配集合就是到根的点。加的边是\(s\to t\),考虑集合变化,也就是到根链的变化,我们从\(x\)开始向上走,找到第一个\(u\)不受\(fa_u\)的控制的点。在这里统计答案。这样的点满足,\(1\to s\to t\to u\),中间不经过\(fa_u\)。然后就判断一下就好了。

卡常,换维是很有用的。

posted @ 2026-08-04 21:43  lghjl  阅读(9)  评论(0)    收藏  举报