AGC025E
不会
首先大胆猜测答案是(sum min(2,c_i)),其中(c_i)表示第(i)条边被经过的次数
我们每次选择一个度数为(1)的点,如果没有经过它的路径就直接过,如果只有一条那么我们可以随便定向,直接把这条路径缩到与它相连的另一个点就行了,如果有两条及以上,我们先任取两条,设这两条氛围是((x,u))和((y,u)),我们可以删掉这两条路径并取一条新路径((x,y)),如果新路径定向为((x,y))那么这两条边就定向为((x,u),(u,y)),显然这样能使(u)到((x,y))路径之间的边全都取到最大值,除了这两条路径之外剩下的直接缩就可以了
CF666E
不会
首先对于所有(T)建出广义(SAM),然后把(S)拿上去跑匹配,相当于询问(S[l..r])对应的节点的最大出现次数
我们对于每个节点建一个线段树,值域为([1,m])表示每个串在这个节点的出现次数,用线段树合并就可以维护了,把询问挂到链上,每次就是查询区间最大值
CF568C
不会
所有条件就是一个(2-SAT),我们从后往前枚举第一个大于原串的位置,然后暴力染色康康是否合法即可
AGC023F
不会
首先合并的时候,前缀(0)肯定全扔前面,后缀(1)肯定全扔后面,所以中间的肯定是若干形如(1111...000...)的段,我们假设有这么两段,分别为(A_1 imes 1+A_0 imes 0)和(B_1 imes 1+B_0 imes 0)
首先混起来放肯定不优,如果按(AB)放,逆序对个数为(A_1 imes B_0),按(BA)放,逆序对个数为(A_0 imes B_1),所以(A)放前面的条件是({A_0over A_1}leq {B_0over B_1})
那么我们每一次选出({S_0over S_1})最小的连通块,若它的根的父亲已经被选,我们直接选了它,否则它一定会在父亲选了之后立刻被选,用并查集+堆维护即可
AGC032C
不会
大力分类讨论
首先这三个环合在一起就是一个欧拉回路,所以必要条件就是每个点度数都是偶数
如果有点度数大于等于(6)肯定有解,因为取这个点,把它出发的所有环拼到只剩三个即可
然后显然如果度数全为(2)或者只有一个(4)都无解,而有(3)个及以上的(4)都有解
然后考虑两个(4),这种情况有解当且仅当我们把度数为(2)的点缩起来之后存在自环
CF585E
不会
我们枚举(gcd),设为(d),如果是(d)的倍数的数有(c)个,那么方案数就是((n-c) imes (2^c-1)),而容斥系数恰好就是(-mu(d))
AGC028C
不会
先考虑所有数都取(A)或(B),那么这样一定可以构成一个环,这个先特判掉
剩下的情况中,必定有一个数同时取(A)和(B),记取不取(A)和(B)分别为(0,1),那么每个数都有四种情况,(00,01,10,11),而且(00)和(11)的数目一定相等
把所有的(AB)都排个序,枚举一个取(11)的数,然后把排完序之后除了这个取(11)的数之外的前(n-2)个取来,用这个更新答案。容易发现,这样一定可以构成一个合法方案(考虑用(00,01,10,11)连成一个环即可,满足相邻两个点连接部分一个为(0)一个为(1))
AGC036F
做过,忘了(这里)
CF521D
首先对于每个数来说,(1)操作最多一次(选最大的那个变),(3)操作永远放在最后进行
把(1)操作也变成一个(2)操作之后我们来考虑,(3)操作会使答案乘上(x),(2)操作会使答案乘上({x+a_iover a_i}),那么我们把所有的(3)操作,以及对于每个(i)每次取出最大的(x),把所有这些倍数放进一个堆里,每次取出最大的用来更新答案即可
更新的时候把(a_i+=x)写成(a_i=x)竟然能炸胡一百多个点,服了
ARC095F
首先发现一点,如果合法,原树必须是一个毛毛虫(即把所有叶子去掉之后,剩下的每个点的度数小于等于(2),也就是说是一条链)
我们记(j')为(to_i),也就是从(i)向(to_i)连的边。考虑反证,假设去掉叶子之后存在某个点度数大于(2),设为(u),那么至少存在两个点满足(to_v=u),不妨设这两个点分别为(v)和(w),由于(v)不是叶子,即存在(to_x=v),而且根据定义有(p_v>p_u),那么显然有(v>u)(否则(to_x)应该取(u)而不是(v)),同理有(w>u)。而(p_v)和(p_w)之间存在大小关系,不妨设(p_v<p_w),那么(to_w=v)(因为(v>u)),而这与我们已知的(to_w=u)矛盾,所以假设不成立
对于方案,我们取出一条直径(包括开头和结尾的两个叶子),对于每个点,设去掉直径之后连接的叶子个数为(w_i),按照(k+1,k+2,...,k+w_i,k)的方式来染就行了(其中(k)代表直径上那个节点,剩下的就是叶子节点)。正反各做一遍就行了
CF708D
不会
首先流量守恒按照循环流那样搞就行了,建一个超级源和超级汇,如果总流量入大于出从(S)向它连边,出大于入就从它向(T)连
然后对于边,如果(cgeq f),先连一条普通边,流(c-f)费(1)(表示扩流),再连一条流(inf)费(2)的边(表示流量和限制一起扩),再连一条反向边流(f)费(1)(表示减流)
如果(c<f),那么我们先手动把限制扩大到流量并累加代价,连一条流(f-c)费(0)的反向边(表示撤销对限制的扩大,同时需要减少流量),以及流(inf)费(2)的正向边(同上)和流(c)费(1)的反向边(同上)
最后加个(n)到(1)的流(inf)费(0)的边,跑个最小费用流就行了
CF585F
不会
我们先把(s)所有长度等于({dover 2})的子串取出来建一个(AC)自动机,把所有(end)节点以及(fail)树的子树中的节点都标记起来,那么一个串合法当且仅当它在自动机上走到过某个标记点
用数位(dp)计算不合法的个数,记(f_{i,j,k})表示考虑到第(i)位,当前在自动机第(j)个节点,(k)表示是否卡到上界,直接转移即可,最后用总数减去不合法的
ARC101E
考虑容斥,强制某条边不选,就是只考虑去掉边后两棵子树的匹配,设(f_{u,i,j})表示考虑到(u),与(u)在同一个连通块的点数为(i),强制断掉的边数的奇偶性为(j)的方案数,转移即可
CF671E
不会,神仙题,这里
CF504E
对于每个点维护到根的路径上的串的正反哈希值,然后二分(LCP)长度,把对应的取出来就行了,由于需要求(k)级祖先可以用长链剖分(O(1)),复杂度就是(O(nlog n))了,剩下的就是调代码了
不过我因为懒直接用倍增,(7.9s)卡过(大雾)
AGC028F
不会,神仙题,这里
AGC035F
做过,这里
CF575I
不会
把每个三角形都拆成三个单点修改,分别和((x,y),(x+y,y),(x,x+y))有关,用二维树状数组维护即可
ARC091F
令(f(n,d))表示(n)个石子,(k_i=d)时的(SG)函数,通(da)过(biao)推(ke)理(de)
归纳证明即可
但是直接算还是会(T),我们注意到第三步的时候所有(leftlfloor{nover d} ight floor)相同的可以一起处理,而不同的(leftlfloor{nover d} ight floor)的个数只有(O(sqrt{n}))个,所以时间复杂度为(O(nsqrt{a_i}))
CF674F
不会
设天数为(c),首先我们发现状态数的上界是(sumlimits_{i=1}^{min(n-1,p)}c^i{nchoose i}),即我们枚举睡觉的熊的数量,以及它们是谁,是在哪一天睡的
而这个上界是可以达到的,我们令每一桶酒对应一种情况,在第(i)天让第(j)头熊喝下所有满足下面条件的酒(x):(x)代表的状态中(j)在第(i)天睡下。这样每种情况都可以被达到了
预处理一下组合数即可,时间复杂度(O(p^3+pq))
CF587D
用(2-SAT),(i)和(i+m)分别表示这条边选不选,分别记为(x_i)和(x_i')
选出来的需要是一个匹配,那么我们对于每个点连出的边,连边(x_i)和(x_j'),但是这样边数是(O(m_2))的
我们将边依次记为(x_1,..,x_d),通过前后缀优化来解决这个问题。设(s_1,..,s_d)和(t_1,..,t_d),连边((s_i,s_{i+1})),(t_{i+1,t_i}),((x_i,s_i)),((t_i,x_i')),((s_i,x'_{i+1})),((x_i,t_{i-1}))(建议画一画图)
这样边数就是(O(m))的了,而且效果和之前一样
而剩下的同颜色也需要是一个匹配,那么我们对于每个点连出的颜色相同的边,连边(x_i')和(x_j),把上面那种反过来就行了
然后二分答案,对于大于答案的边连边((x_i,x_i')),跑个(2-SAT)即可
然后是我的另一种想法……由于要输出方案会比较麻烦所以被我pass掉了
首先二分来强制某些边不能选就是了
只考虑一种颜色的边时,每个点度数必然小于等于(2)否则无解
那么此时每个连通块必然是环或者链
如果是环,那么有两种匹配,而且不管哪种,环上所有点都不能再选了
如果是长度为奇数的链,两种匹配里除去两端之外中间的点都必然被选,而两端的点同时选或不选,那么肯定是贪心的不选两端的点最优(前提是这种匹配方案对应的边都小于等于二分的值)
如果是长度为偶数的链,中间的点必然被选,而两种匹配分别对应两端的点被选,设端点分别为((u,v))
我们在新图里将((u,v))连边,那么新图中每条边要分配一个点,那么对于每个连通块的充要条件就是(|E|leq |V|),必要性显然,充分性的话,因为这样的连通块必然是树或基环树,树只要把每条边匹配给儿子,基环树把环上边点对应分配之后,下面的子树每条边也是匹配给儿子。所以用并查集判断一下就行了
不过想想就很麻烦……
ARC096E
不会
考虑容斥,我们枚举有(i)个数字出现次数小于等于(1),那么把这(i)个数字划分到(j)个集合中,选的数就是对应集合中的数。由于可能存在数没有出现,我们加一个数字(0),将(i+1)个数字划分为(j+1)个集合,和(0)在同一个集合中的数字视为不存在,方案数即为(egin{Bmatrix} i + 1 \ j + 1 end{Bmatrix})
所以最终答案就是
CF685C
不会
由于是曼哈顿距离,我们可以转切比雪夫距离之后二分答案,由于转距离的本质就是枚举绝对值的正负,所以((x,y,z))转化之后的坐标就是((x+y+z,x+y-z,x-y+z,-x+y+z)),而二分之后要求我们的四维都在某个范围内
令(a=x+y-z,b=x-y+z,c=-x+y+z),则(a+b+c=x+y+z)且(amod 2=bmod 2=cmod 2),所以我们可以通过(a,b,c)唯一确定(x,y,z)
枚举(amod 2),然后移项整理可得
那么判断([l_1+l_2+l_3,r_1+r_2+r_3])和([l_0,r_0])是否有交即可
CF587F
不会
设阈值(S=sqrt{100000}),并建好广义(SAM)
如果(|s_i|>S),那么我们把所有这样的(s_i)离线下来,数量不会超过({nover S})个,对于每个这样的串,在(parent)树上(dfs)一遍来求出(1)到(n)每个串在(s_k)中的出现次数,那么询问就可以(O(1))回答了,这一部分的复杂度是(O(nsqrt{n}))
如果(|s_i|<S),我们将其拆成((s_i,r))和((s_i,l-1)),然后用扫描线维护,当加入(l-1)或者(r)时,枚举(s_i)的每一个前缀,查询这个前缀的祖先有多少个被扫到,用(dfs)序就可以变成一个区间修改单点查询的问题,因为会进行(O(n))次修改和(O(nsqrt{n}))次查询,我们用修改(O(sqrt{n}))和查询(O(1))的分块即可(其实直接用树状数组就可以过了)
时间复杂度(O(nsqrt{n}))
AGC026E
不会
首先把原串分成尽可能多的段,使得每段(ab)个数相等,那么我们每段的操作就是独立的了
对于每一段
-
如果这段开头是(a),那么对于任意(i)都满足第(i)个(a)在第(i)个(b)之前,最优方案一定是形如(ababab...)的,我们贪心求出最长的能选的就是了
-
如果这段开头是(b),那么对于任意(i)都满足第(i)个(b)在第(i)个(a)之前,而如果选了第(i)组一定会选第(i+1)组,因为它们的相对顺序一定是(b_i,b_{i+1},a_i,a_{i+1})的样子,所以我们枚举选最后(x)组就行了
然后合并答案的时候从后往前,如果当前这一段大于等于后面的最优答案就接上去,否则扔掉
AGC031D
不会
首先(p,q)可以看做两个置换
(f(p,q))表示的置换中的第(p_i)个元素是(q_i),也就是(p_i o q_i)
那么让我们康康啊,(p)代表(i o p_i),(q)代表(i->q_i)……
那么(qp^{-1})就代表(p_i o i o q_i)了
所以(f(p,q)=qp^{-1})
然后大力推出前几项
令(A=qp^{-1}q^{-1}p),可以归纳证明得出(a_n=Aa_{n-6}A^{-1}(n>6))
然后就是上置换的快速幂就行了
CF590E
不会
首先我们建出(AC)自动机的(fail)树,并把每个串放在对应的节点上,然后枚举前缀,向(fail)树上所有祖先节点对应的串连一条边,这样最后就是一个(DAG)了
不过这样会(T),注意到子串关系存在传递性,那么我们每一次只向(fail)祖先节点遇到的第一个串连边,最后跑个传递闭包就行了
如果我们将(s)是(t)的子串记为(sleq t),那么我们发现这是一个偏序关系,满足自反性,对称性和传递性。所以我们现在的问题就是对于一个给定的偏序集求一个最长反链的方案
具体做法就是建一个二分图,左边的(x)和右边的(y)有边当且仅当(xleq y),求出一个最大匹配之后,从左边每一个非匹配点开始(dfs),从左往右只经过非匹配边,从右往左只经过匹配边,最终取所有在左边被(dfs)到且在右边没有被(dfs)到的点就是答案,具体证明看这里
AGC021E
做过,这里
AGC036E
不会
可以转化成从(S)中删去尽量少的字符,首先考虑到相邻且相同的是没有用的,我们只保留其中的一个
不妨设三种字符的出现次数从小到大依次为(cnt_A,cnt_B,cnt_C)
当(cnt_C>cnt_B)时
-
如果存在(C)满足左右两边字符不相等或者在序列两端,直接删掉
-
否则,删掉一个形如(ACA)中的(CA)
显然这样操作之后三种字符大小关系不会变化,一直操作到(cnt_B=cnt_C)为止
当(cnt_B>cnt_A)时,不断找到两边字符不同的子串(BC)或(CB)删掉,由于(cnt_A)最小,所以一定存在
用双向链表维护,时间复杂度(O(n))
CF603E
不会
首先,存在一个边集使得所有点度数为奇数的充要条件是每个连通块都有偶数个点
必要性显然,因为一条边提供的度为(2),所以一个连通块总度数必然为偶数,那么点数为奇数且度数全为奇数显然不可能
充分性得到话,我们随便取一棵生成树,从底往上考虑每个点的父亲边是否留下,这样除了根之外每个点都必然度数为奇数,而由于总度数为奇数,所以根显然也是度数为奇数
我们注意到,如果加入了一条小于答案的边,那么无论如何答案都不会变大,所以我们可以用一个类似(kruskal)的方法,加边到不存在度数为奇数的连通块为止,此时的最后一条边的边权就是答案了
而对于每个点都要计算答案,我们可以整体二分,离散化权值之后,设(solve(l,r,x,y))表示考虑([l,r])之间的边且答案为([x,y])的情况,首先将所有([l,mid])之间权值小于(x)的边加入,然后再将权值在([x,y])之间且在(mid)左边的边加入直到不存在度为奇数的点,此时的边权就是(mid)的答案了。往右递归需要将([l,mid])中小于(x)的加入答案,往左递归需要将([x,ans_{mid}-1])中小于(l)的加入答案