Atcoder总结 Part III

AGC3F Fraction of Fractal

首先先判掉两个特殊情况

如果将两个原来的矩阵上下或左右拼在一起黑色的块都是联通的,那么最终图形中联通块的数量只有1个

如果将两个原来的矩阵上下或左右拼在一起黑色的块都不连通,那么最终图形中联通块的数量就是原来图形中黑色块数量$V^{k-1}$

那么现在的情况就是上下或左右中有一个是连起来成为一个联通块

其实这里并不需要用平面图上的欧拉定理,由于只有一个方向会产生新的边,并且原来的图只有一个联通块,那么只要数产生的新边$E$有多少个,那么答案就是$V^{k-1}-E$,这样就避免了难以统计的平面个数

考虑$E$如何得到,设原来的图中这个方向上的变有$a$个

那么$E_k=aV_{k-1}+E_{k-1}$

其中$V_k=V_1V_{k-1}$

直接矩阵快速幂即可

主要这道题需要把两个特殊情况判掉,否则会陷入恶心的平面个数的统计中去,像这种情况不太多的题目,不要一上手就试图用一个算法把所有情况都考虑进去,可以分开考虑,这样会更清晰一点

代码

ARC93F Dark Horse

首先可以看出某个区间的获胜者,如果这个区间不存在$1$,这个区间的胜者是这个区间的最小值

那么可以把比赛的过程看作一棵树,那么最终根节点是要为$1$,考虑$1$的路径上每一次比赛的对手,每一个对手都不能是$A$中的数,从下往上依次标深度

如果直接算是不好算的,考虑容斥

设$S$为路径上对手为$A$中的深度的集合,设$f(S)$为$S$这个集合的方案数

答案就是$\sum\limits_S (-1)^{S}f(S)$

考虑如何算出$f(S)$,由于$1$在每一个位置上都是等价的,那么只需要考虑某一个位置出发,可以设$dp[S]$表示哪些深度的路径已经有$A$中的数了,然后从大往小的去转移即可

代码

AGC34F RNG and XOR

跟ZJOI2019开关几乎一样

首先设$dp[mask]$表示从当前数为$mask$期望要从$0$变化多少次

可以列出方程$dp[mask]=1+\sum\limits_{i=0}^{2^n-1}p_idp[mask\bigoplus i]$,其中$p[i]$为产生第$i$种操作的概率

并且$dp[0]=0$

那么可以设$F$为$dp$的集合幂级数,$G$为$p$的集合幂级数,$H=\sum\limits_S x^S$

那么$F=H+GF+cx^{\emptyset}$

由于$dp[0]$是一个特殊的点,不满足上面的方程式,那么需要单独拿出来待定系数

设$\overline{F}$为$F$的$FWT$的结果其他的同理

$[x^S]\overline{F}(1-[x^S]\overline{G})=[x^S]\overline{H}+c$

其中

$[x^S]\overline{H}=\sum\limits_T(-1)^{|S\cap T|}$

$=\sum\limits_{i=0}^{|S|}(-1)^i\binom{|S|}{i}2^{n-|S|}$

$=2^n[|S|=\emptyset]$

可以发现如果$[x^{\emptyset}]\overline{G}=1$时当且仅当$S=\emptyset$

那么$c+2^n=0,c=-2^n$

那么对于$S\neq \emptyset$

$[x^S]\overline{F}=-\frac{2^n}{(1-[x^S]\overline{G})}$

就可以预处理$G$的$FWT$结果,来计算每一个$S\neq \emptyset$

那么主要是要求出$[x^{\emptyset}]\overline{F}$

由于$dp[0]$的值很特殊是一个已知的常数

那么考虑$IFWT$的结果

$0=[x^{\emptyset}]F=\frac{1}{2^n}\sum\limits_S [x^S]\overline{F}$

在右边的和式中提取出那么$[x^{\emptyset}]\overline{F}$这一项来

那么$[x^{\emptyset}]\overline{F}=-\sum\limits_{S\neq \emptyset} [x^S]\overline{F}$

那么求出$F$的$FWT$结果后就直接$IFWT$回去即可

对于开关那道题来说还需要再推几步

考虑答案就是$[x^S]F$

$[x^S]F=\frac{1}{2^n}\sum\limits_T(-1)^{|S\cap T|}[x^T]\overline{F}$

将$\emptyset$的情况单独拿出$ans=\sum\limits_T(1-(-1)^{|S\cap T|})\frac{2}{(1-[x^S]\overline{G})}$

$ans=\sum\limits_T[|S\cap T|\%2=1]\frac{2}{1+\sum\limits_{i\in T}p_i-\sum\limits_{i\notin T}p_i}$

$ans=\sum\limits_T[|S\cap T|\%2=1]\frac{1}{\sum\limits_{i\in T}p_i}$

这个直接做一个0/1背包即可,顺便记录当前1个数的奇偶性

代码(AGC34F)

AGC20D Min Max Repetition

想都想到了,可就是没想到二分,小编也很惊讶

首先最初的想法是,把每一个$B$作为一个分隔板,将$A$平均的放进去,或者$A$做分隔板,将$B$平均的放进去

那么得到的最小的连续段就是$k=\max(\left \lceil \frac{a}{b+1} \right \rceil,\left \lceil \frac{b}{a+1} \right \rceil)$

那么再考虑如何保证字典序最小

肯定是先贪心的放$A$,把$B$放到后面去,那么就可以$A...ABA...ABA...$这样去放,但是会发现之后可能$B$有多余的,那么就需要用尽可能少的$A$去隔开这些多余的$B$

那么后面大概是这样的$B...BAB...BAB...$

那么在$A...ABA...ABA...$和$B...BAB...BAB...$之间会存在一个分界线,那么要尽量把分界线向后移

设前面$A$用了$U_a$个,那么用$B$的个数为$\left \lceil \frac{U_a}{k} \right \rceil-1$

设剩下了$A$的个数为$R_a$,B的个数为$R_b$

那么后面那一串需要满足的条件就是$2(R_a+1)\geq R_b$

那么之间二分这个分界线即可

代码

ARC103F Distance Sums

我先是考虑距离之和最小的节点一定是在重心这个位置的,那么考虑在它下面连节点,然后可以发现某一个节点子树的大小是可以通过父亲和当前节点距离和的差值得到的,具体来说是这样的$d_{fa}-size_x+n-size_x=d_x$

但是从根节点向下构造不好构造,因为儿子可能有很多个,但是父亲只有一个,这就启发从下往上构造

考虑把所有节点的$d$排序,然后从大往小去扫描,遇到某一个节点的时候,去找和当前子树大小匹配的节点,如果找不到那么数据不合法,如果找到了,那么就把子树大小加到那个节点上,并把那个节点设为当前节点的父亲

最后需要$dfs$一遍判断构造出来的结果是否和输入的一致

代码

AGC13E Placing Squares

首先需要把二次方的贡献转化成把两个不同的求放到$x$个不同的盒子里去,那么方案数就为$x^2$,那么这里就是把正方形的边当作有边长个盒子,存在若干个隔板,相邻两个隔板之间就是一个正方形,那么在隔板内放两个不同的小球,最后得到的方案数就是需要统计的答案

考虑设$dp[i][0/1/2]$表示到当前第$i$个位置,最后一个隔板到现在放了$0/1/2$个小球的方案数

如果当前不放隔板$dp[i][0]=dp[i-1][0]$,$dp[i][1]=2dp[i-1][0]+dp[i-1][1]$,$dp[i][2]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]$,其中在放一个球的时候需要先确定放了哪一种球,所以有两种放法,最后放到两个球的时候就不需要再次区分是哪一种球了(当然也可以在放到两个球的时候去区分)

如果当前放隔板,那么新放的隔板需要当前已经放到$2$个球,那么$dp[i][0]$需要加上$dp[i][2]$,也就是$dp[i-1][0]+dp[i-1][1]+dp[i-1][2]$

直接矩阵快速幂即可

由于题目中存在一些不能放隔板的位置,那么这里的矩阵就不存在放隔板的转移,那么单独拿出来做一遍矩阵乘法即可

代码

AGC17F Zigzag

由于要使后面一条的折线在前面一条折线的后面,那么可以考虑枚举前一条折线的状态,来转移当前这条折线的状态,直接做的话是$4^n$的复杂度

考虑如何优化,其实没有必要直接枚举前面每一个位置的状态,可以像轮廓线$DP$一样,记录当前这一条折线前面的状态和上一条折线后面的状态,每一次转移转移一格,还需要记录在这个状态之前上一层走到了哪里,那么总共有$nm$个状态,每一次转移$O(n2^n)$

可以设$dp[i][j][mask]$表示当前为第$i$条折线,当前转移到第$j$层,$[0,j-1]$位记录的是第$i$条折线的状态,$[j,n-1]$记录的是第$i-1$条折线的状态

考虑如何将上一层走到了哪里的状态压掉,可以发现在我们记录的状态里面有很多状态是无用的,具体的说,假设当前在第一层,那么只有枚举到上一条折线右边是合法的状态,那么考虑将$dp$的状态中$mask$改为表示限制的区域

画几张图可以发现,只有当前走的是$1$,边界为$0$的时候需要修改边界,设当前转移到第$j$层,如果在限制条件的集合$S$,中不存在某一位$k$,使得$k>j$并且$k$为上为$1$的话,需要修改第$k$位为$0$,第$i$位为$1$,否则只修改第$i$位为$0$

那么转移可以做到$O(2^n)$

总时间复杂度$O(nm2^n)$

代码

AGC49D Convex Sequence

由于问的是一个凸包,考虑差分两次之后,每一位就是一个非负数,相当于对于某一个后缀或者前缀加上$1,2,3,...$,这样统计相当于把贡献在$1$的位置进行统计

还有注意到由于每一位的贡献都是一个平方级别的数,那么这样位最多只有$O(\sqrt(m))$个,那么可以直接无限背包进行统计

考虑将每一种方式在序列中的最小值处进行统计,最小值为值为第一关键字,下标为第二关键字,那么对于最小值的位置$i$,$i-1$的位置上一定要加上$1,2,3,.....$,那么扫过去动态维护背包,需要删除和加入总复杂度$O(m\sqrt(m))$

现在统计的是最小值为$0$的情况,还可以整体加$1$,对应$m-kn$的也需要统计

代码

AGC33E Go around a Circle

首先考虑串只由一种颜色组成,假如是$R$,那么环上不能存在长度大于$1$的$B$连续段,这个可以通过$DP$来处理(同下)

那么接下来如果有两种颜色,还是假设开头那个颜色为$R$,首先可以发现的是环中仍然不能存在长度大于$1$的$B$连续段,那么环一定是由若干$RRRR...RB$组成的,那么现在考虑对于某一个确定的染色方案,来构造字符串

对于某一个$B$连续段,肯定是在那个$B$之间反复横跳,那么在跳完一段$R$连续段之后一定要跳到这个连续段之前或者之后,那么环中中$RRRR...RB$不能太长,否则就跳不到$B$旁边

具体来说,假设当前讨论的$R$连续段不是开头的那一段,那么在走到这个$R$连续段之前,跳到的位置一定是在某一个$B$旁边,并且对于每一个$B$旁边都至少有一个初始位置可以到达的地方(归纳可证)。 如果某一个$R$连续段长度是偶数,那么在$B$旁边那一个$R$弧上反复横跳即可,最终会回到原来位置,这个情况不构成限制;如果某一段$R$连续段长度为奇数,那么需要跨过一个$R$连续段,走到另外一段去,那么$R$连续段长度一定需要为奇数,这样才能到了另一端后,变成偶数的情况可以待在原地

那么环中最长$R$连续段长度不能超过,给定串最长长度为奇数的$R$连续段长度(不算开头和结尾)

对于开头那个连续$R$段也会产生限制,如果长度$l$,产生限制为$l+[l\%2==0]$

那么现在相当于要将环划分成若干偶数段,并且长度有限制

考虑如果直接环上$DP$不好做,那么考虑破环为链,可以考虑枚举$1$号点右边的那条边所在$RRR...RB$段长度,可以设$dp[i]$表示长度为$i$的链划分方案数,那么答案即为$\sum idp[n-i]$

代码

AGC51D C4

首先需要将路径每两步拆分,这题的重点在这里,这样拆的好处是,得到的6种路径的数量都可以分别求出,就避免两条边混在一起的情况,并且原图是对称的,选取2或4是较好的选择,比较得到2较好

然后开始做题

首先可以将路径分成$S\rightarrow U,U\rightarrow S,S\rightarrow S,U\rightarrow U$,其中$S\rightarrow S,U\rightarrow U$可以再分别分成过$a,d$和$b,c$,各两种

首先$S\rightarrow U$的数量等于$U\rightarrow S$的数量,假设都为$i$,再确定经过$a,b$边的个数有$j$个,那么经过$c,d$边的个数有$2i-j$个

考虑将其他两种插入到序列中,其中$S\rightarrow S$有$i+1$个位置,$U\rightarrow U$有$i$个位置,由插板法可得

$\sum\limits_{i,j}\binom{2i}{j}\binom{\frac{a-j}{2}}{\frac{a+d}{2},\frac{d-(2i-j)}{2},i}\binom{\frac{b+c}{2}-1}{\frac{b-j}{2},\frac{c-(2i-j)}{2},i-1}$

展开得

$\frac{(2i)!(\frac{a+d}{2})!(\frac{b+c}{2}-1)!}{i!(i-1)!}\sum\limits_{i}\sum\limits_{j}\frac{1}{j!(\frac{a-j}{2})!(\frac{b-j}{2})!}\frac{1}{(2i-j)!(\frac{d-(2i-j)}{2})!(\frac{c-(2i-j)}{2})!}$

然后$ntt$优化即可

代码

ARC110E Shorten ABC

首先将$A,B,C$分别看作数字$1,2,3$,每一次操作就是把相邻两个不同的数字替换成其异或值

然后可以发现一段区间如果只要不是全部相同,那么一定可以缩成一个字母,并且不管操作顺序如何,这个字母都是固定的

考虑一个如何判断一个字符串是否可行,那么这个字符串的异或和一定是跟原串的异或和相同,并且其中一个字符一定对应着原串的一个连续的字串

那么每一次将一个字符替换成最短的子串,最后判断剩下的是否异或和为$0$,这样不会算重

这个拿一个$dp$计算即可

代码

posted @ 2020-12-07 16:59  SevenDawns  阅读(108)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end