不分了,反正也没做多少题
“寒假”作业
1.101221I,Sensor Network
https://codeforces.com/gym/101221
题意:给(n<=100)个网格点,距离小于(d)的点两两连边,求最大点集使得每个点两两连边
奇妙的转化思路
选定两个点(i,j)作为最远点,以(dis(i,j))为半径,(i,j)为圆心作圆,可以发现圆交集里的点被线段(ij)分成了两部分,同部分的点两两距离都小于(dis(i,j)),于是转化成了二分图求最大团
二分图求最大团可以用最小点覆盖做,即将连边条件改为距离大于d,删去最少点使二分图无边,而最小点覆盖等于最大匹配,求出最大匹配后可以暴力求出删去哪些点
2.101239E,Evolution in Parallel
https://codeforces.com/gym/101239
题意:给(n+1(nle4000))个字符串,求将(2-n+1)个字符串分成两部分,两个序列(p,q)满足(S_{p_{i+1}}subseteqq S_{p_i},S_{q_{i+1}}subseteqq S_{q_i})
求序列,若无这样的序列或第一个字符串不包含其他所有字符串则输出无解
按长度从大到小做,1.放p里,2.放q里,3把p退到能放i,再把退出来的字符串放到2里,若3无法实现,则无解
可以这样理解,往q放的都是p放不了的,若p,q都放不了,存在一种合法情况便是存在(p_j)可以接受(i),且(p_j)后面的串都可以放到(q),
否则便是(p_j)下面的串没地方放,不合法
4.100269C,Correcting Curiosity
https://codeforces.com/gym/100269
给出两个字符串(A)与(B),长度小于2000,通过一步操作将A换成B
操作为:a串,b串,即先找出A中所有a(不重叠),将其转换为b,如:abababa, aba ab,则改为abbab
让a+b(长度)最小
5.101190C,Cactus Construction
https://codeforces.com/gym/101190
给一棵有标号(1~n)仙人掌,现在有n个点,每个点为一个集合
操作1:x所在集合中颜色为a的染为b,操作2:x所在集合与y所在j集合合并,操作3:x所在集合颜色i与颜色j的点连边
给出方案,步数小于1000000,不得用大于4种颜色
从下往上做,先假设是一棵树,设子树i的集合中颜色1为孙,2为儿子,3为根
在回溯到一个点时,将它儿子集合与它合并,23连边,离开一个点时,把2(儿子)改为1,3(根)改为2
这样分层做可以保证根只会与儿子连边
然后是仙人掌,情况类似,只要扫到环的底部将环的底部(buttom)和顶部(top)先合并连边,再保证这个操作不会对(top)的其他“子树”产生影响,剩下的就跟树的情况一样了,需要使用颜色4
1为废点,2为儿子,3为自己,4为返祖,保证同一集合内有且仅有一个点为3或4
首先每个点都是1,从根往下搜,
到(i)时,先做完每个儿子,然后把当前点定为3,一个一个儿子合并,((3,2))连边,然后将2改为1,3改为2,处理返祖,此时只有一个2
祖先设为4,((4,2))连边,一个点至多一条返祖
本来这道题题解到这里该打完了,然而我check时被提示了一个我码之前想到的,却在问别人时忘掉了的问题,一个点同时为两个环的顶部时,两个环会提前并在一起,导致后处理的环在回溯连边时把前者环的2也连了
所以得改,其他不变,儿子分为三类,有返祖且边不连向自己的,子孙有返祖边且不连自己的,其他
先把第三类点集与自己合并,4改2,再合并第一类点集合,((3,4))连边,再合并第二类,((3,2))连边,2改1
最后处理自己颜色,如果自己有返祖边就把当前点改为4,然后打上标记并上传,否则改2
12.100851D,Distance on Triangulation
给定一个正(n)边形及其三角剖分, 共(2n-3)条边 ((n)条多边形的边和(n-3)条对角线), 每条边的长度为1。
共(q)次询问, 每次询问给定两个点, 求它们的最短距离。
考虑到边不会交叉,对于一个正(n)边形与其中一条边((i,j)),这条边左边的点到右边必然要经过(i/j),右边的点到左边同理,如果询问中两个点被分到了两边,我们可以用他们到(i/j)的最短距离,四种情况组合一下取最小
接下来做法就比较明显了,对当前图形选择一条能把图分成尽量均匀的两部分的边((i,j)),处理左边右边的点到(i/j)的最短距离,然后处理跨过中间的询问,将图与剩余询问分成两部分,接着分治,时间复杂度大概是(O(nlogn))的
存当前图的点可以用(vector),或者用一个类似栈的东西暴力存点和边,用完弹出,找边时暴力枚举存下的边判断均匀
一开始T飞了,后来打了个剪枝,没有询问就退出跑的飞快
3.28
T1 制作美食
满足(yle a_x 且 xle b_y),可以看成线段((x,0)-(x,a_x))与线段((0,y)-(b_y,y))有交
简单画一下图可以发现,按(b_y)与(x)从大到小做,就满足了(xle b_y)
将(y)塞到线段树里,如果一条(a)线段与多个(b)线段有交,只有(y)最小那个有用,其他都可以删掉
于是每次找到(a)第一个与(b)线段的交点,然后在线段树上查询、删除后继
最后的联通块个数就是没有被删掉的(b)线段与找不到交点的(a)线段个数
(O(nlogn))T成60
atcoder C
可以发现乘上的数大于1的至多只有20个,其他都是没用的
设(f_{i,j})表示乘了(i)个大于1的数,末尾大小为(j),暴力转移即可,复杂度调和级数乘20
比赛时以为转移会T打了整除分块还没调出来
3.29
T1 6085. 【GDOI2019模拟2019.3.26】要换换名字
首先答案满足二分性
暴力枚举ans,每次将(i)可以变的等于ans的长度的名字搜出来,连边,跑二分图最大匹配
可以发现(i)连的边等于(n)时必有名字可以分配,因此最多(n^2)个点,建图时优化一下即可通过
T2 6086. 【GDOI2019模拟2019.3.26】动态半平面交
题意与名字无关
考虑离线,设询问深度为(t_i=deep_{u_i}+d_i),按深度从小到大插入点和处理询问
插入查询都在线段树上按(dfn)处理,插入直接乘上(a_i),查询直接查整棵子树,考虑对重复质数去重
对于每个质数的前二十五次幂建(set),假如(a_i)为(2^3)则将(dfn_i)扔进2的前三个(set)中,每次查前驱后继,在与前驱,与后继的(lca)处分别乘(cfrac{1}{2}),由于前驱与后继的(lca)之前去重过了,因此在前驱与后继的(lca)处乘2,可以发现不会重复
时间是(25nlogn)的
在线把线段树改成主席树即可
然而此题还没调出来
T3 6087. 【GDOI2019模拟2019.3.26】获取名额
泰勒展开,不会
3.30
T1 7035. 2021.03.30【2021省赛模拟】神奇纸牌(uno)
考场这题打了两个多钟暴力,然后发现是道DP水题,没调出来,考完两分钟发现可以快速幂
可以发现可以将四种颜色变为四个联通块,如果有相同数字就合并联通块
设(f_{i,s})为选了前(i)个数后联通块状态为(s)的方案数,(s)以并查集的形式压缩,联通块(i)的父亲编号小于等于(i),为(0)则代表此颜色未出现过,则有(2*3*4*5=120)种状态,暴搜一下即可,其实去掉不合法的只剩不到三十种状态
状压DP的转移是固定的,矩乘快速幂,最后枚举一下合法状态即可
T2 7036. 2021.03.30【2021省赛模拟】凌乱平衡树 (treap)
暴力模拟可以拿到(95)分的好成绩
首先原树的答案很好算,(rotate)也只是某些(sz)加加减减修改答案
考虑合并,由于只有(a)树的右链与(b)树的左链有关,我们把它们提出来,其一定是从大到小排列的
把他们归并排序后观察对答案的影响,形如(a_i,a_{i+1},a_{i+2},b_i,b_{i+1}····)会对答案产生(3*sz_{b_{i}})的贡献,因为(b_i)的子树全体深度加了一
那么修改也比较好处理了,我们将(a,b)存到两棵权值线段树上,(rotate)时插入删除一下,插入时找一下(a、b)的前驱后继,看是放在了一堆(a)开头、中间还是(b)中间,分类讨论修改下贡献就好,删除类似
由于是双关键字排序,我们插入时将(a_i)乘二加一,将(b_i)乘二,就不用讨论是(a)是(b)了
犯了形如忘记插入,打错分号,情况讨论错了之类的错误,爷调了六个小时
T3 7037. 2021.03.30【2021省赛模拟】打扫笛卡尔
(deep)和转化为(sz)和行云流水
设(f_n,g_n)分别为(n)个点时的答案与扫到的点(deep)和的期望
(f)与(g)右边的求和每次只会多乘一个(n),加一个(f_n)或(g_n),可以边处理边更新,(O(n))
4.1
T1 7038. 2021.04.01【2021省赛模拟】异或 (inception)
去年十月做过的原题,当然我啥都不记得了
考虑到一个集合内异或起来最小的一定是一对大小相邻的数,因此保证大小相邻的数异或起来大于限制即可
在(trie)上模拟DP,在(trie)上跑时记录一下(y)表示二进制下,(a_i)的前(j)位与(y)代表的前(j)位异或起来与限制前(j)位相同,分类讨论一下转移即可
4.2
T1 6149. 【GDOI2019Day1模拟2019.4.28】盗梦空间
对每组询问建虚树,分类讨论下在空子树内,虚树边和虚树点上的情况即可
码量惊人,也懒得想
T2 6150. 【GDOI2019Day1模拟2019.4.28】爱乐之城
大缝合题
求
考虑预处理(g(n),f(n),nin[1,maxn])
(g(n))显然可以线性处理,(f(n))可以枚举(d)的倍数,增量处理,前缀和求,(O(nlogn))
我比较蠢,(φ(i))用的是(φ(n)=nprod(cfrac{1}{p}(p-1))),线筛求后面那个系数再乘(n)求的,但好像可以直接筛
至于(F(S)),构造(h(n))使得(f(n)=sum_{d|n}h(d)),则
将后面的(prod g(a))看成(h(d))的系数的一部分,枚举(d),则
后面的(prod_{d|a_i}(g(a_i)+1))即系数,容易发现每加入一个(a_i)只会对约数个(d)产生影响
由于题目保证每个(a_i)各不相同,加入(a_i)找约数(d)复杂度最劣相当于枚举(d)的倍数,即调和级数,质因数分解后直接找约数修改系数更新即可
是为数不多我完全理解了的纯数论题,对个人于数论几个小知识点的学习都有所帮助
4.3
T1 7041. 2021.04.03【2021省赛模拟】Alice 和 Bob 双在玩游戏(gametwice)
简单博弈,但我没做
设DP(f_i)表示在(i)有颗石子,通过移动这颗石子,(i)的主人最多能比对方多走(f_i)步
转移为(f_i=max(0,1+f_u(c_u=c_v),1-f_v(c_u
e c_v))),最后做个背包统计一下方案数,只要存在石子的点中,Alice的(f)和大于Bob的,便是(Alice)胜利
T2 7042. 2021.04.03【2021省赛模拟】时代的眼泪·SP(tearssp)
考试时读错题爆零了,现在也还没改
分块处理,对于整块散块都是暴力一个一个跳
考虑到整块中如果存在一个点(x),往上跳后发现(fa_x)已经被(y
e x)到达过了,那就可以把(x)删掉了,因为接下来不管怎么跳,(y)都会在(x)的正上方,(dep)自然更小
这样每个块至多遍历整棵树一次,也就是(nsqrt{n})的
对于散块,我们记录一下(i)所在块跳了多少次,(i)自己跳了多少次,补齐差的次数,如果被删掉过看一下现在的新位置能不能放回块中
由于不能带(log),因此要(nlogn)长链剖分预处理,来达到(O(1))求(i)的(k)级祖先
4.5
T1 7044. 2021.04.05【2021省赛模拟】悄悄话(word)
最近比赛时傻傻的总差一步想到正解(不过题面好有意思)
建(AC)自动机,考虑到一个字符串所包含的所有子串,一定能通过跑(fail)链到达此字符串某个前缀的尾结点上
设(f_i)为以节点(i)代表的字符串或其后缀为结尾的最大答案
我们建个(fail)树,每次查询时,在(trie)上经过每个节点(i)时都查询一下其在(fail)树上的对应答案(f_i)用来更新答案,跑到尾结点时用取(max)的方式更新尾结点在(fail)树上子树的(f),复杂度(O((sum len_i)logsum len_i))
T2 7045. 2021.04.05【2021省赛模拟】数学考试(sleep)
比较经典的网络流题,但我没想到,考场打的几档分挂光了
考虑用网络流,对于每个(x)建一条长链从(S)到(T),每条边为权值
对于每个限制(x_ule x_v+D),转化为(x_u-Dle x_v),对于(x_u)链上每个点,对(x_v)链上对应(x_u-D)的点都连一条权值为(inf)的边,对于任意(x_u=i)的点,要么是选了(x_u=j(jle i)),要么选了(x_v=k(kge i-D)),这样就一定满足了限制
4.7
T1 7047. 2021.04.07【2021省赛模拟】染色(coloring)
今天比较摸
考虑到每个斜线被替代当且仅当其所有行被染色
问题转化为有(n+m-1)个区间,可以选择一些区间,然后在这些区间的并里选一些元素,但不能有所选区间的元素被全部选择,问方案数。
可设(f_{i,j})表示第(i)个斜线不染色且其区间倒数(j)个元素染色,方案数是多少,(g_i=sum f_{i,j}),(g_0=1)
因为从左到右的斜线,其所在行的区间左右端点单调不下降,因此设倒数(j)个元素
三种转移,分别是两个区间不相交,相交且(i)后面的连续选的元素与(j(j<i))不相交,两个区间相交且(i)后面的连续选的元素与(j(j<i))相交
对于第一种,(lim[i][0])到(lim[i][1]-k-1)与与前一个斜线都可以随便选,(f_{i,k}+=g_j*2^{lim[i][1]-k-lim[i][0]}),中间的行因为被选了的斜线完全覆盖了,所以全是被染了色的,方案唯一
对于第二种,从(lim[j][1]+1)到(lim[i][1]-k-1)可以随便选,斜线(j)的方案也是随便选,(f_{i,k}+=g_j*2^{lim[i][1]-lim[j][1]-k-1})
对于第三种,方案数已经被前面的选择固定了,(f_{i,k}+=f_{j,lim[j][1]-(lim[i][1]-k)})
最后把所有方案数加起来即可,包括(g_0)