Codeforces Round 943 (Div. 3) D-G2

Codeforces Round 943 (Div. 3)

origin:https://www.bilibili.com/video/BV1wx4y1z76v/?spm_id_from=333.337.search-card.all.click&vd_source=66ac5da514fe1be9729ebba538a11951

1968D-枚举

思路:

每个人走的位置最多会形成长度为n的环,所以直接枚举走到某个位置之后后面就不走了的所有情况的最大值,相互比较即可

点击查看代码

1968E-构造

题意:

F(Ai,Aj)=|xixy|+|yiyj|,在NN的矩阵中选n个点使所有不同的F(Ai,Aj)=|xixy|+|yiyj|数量最多

思路:

NN中曼哈顿距离的范围为[0,2(n1)],如果全放对角线,那么能得到的曼哈顿距离全是偶数且是范围内的所有偶数,能不能改变一些位置之后把奇数进去?可以发现如果将一个点和相邻的一个点行或列相同,则他们的曼哈顿距离会-1,然后这个点与其他点的曼哈顿距离也都减了1或加了1,可以构造出奇数来。

1968F-枚举 二分

点击查看代码

题意:

如果一个数组可以分成大于等于2的连续子数组,每个连续子数组的异或和都相等,那么这个数组叫做好数组

给一个长度为n的数组,给出q个询问,每次询问给出L,R,问能否数组[L,R]是不是一个好数组

思路:

要算连续子数组的异或和,考虑用前缀异或和维护,

对于[L,R]的数组,如果总的异或和是0,那么总能在中间找到一个分界点使左右两边相等,

如果总的不为0,那分出的字段应该是奇数个,不可能为偶数个,如果为偶数个总的异或和应该为0。如果为奇数个那么三个段其实就够了,因为如果分的段数大于3是可以变成3段的,比如五个段TTTTT,对于中间三个T,合并之后异或和为T,就变成了TTT,考虑三个段的情况,设第一段的右端点为X,第二段的右端点为Y,则整个序列为LXYR

那么L<=X<Y<R,如何找到X,Y的位置? 对于2、3段来说,总异或和为0,也就是说s[R][X]==0s[R]=s[X]

同理s[L1]=s[Y],保存相同S[i]的下标然后二分查找

点击查看代码

1968G1-z函数 二分

题意:

定义Fk表示将字符串S分成k个连续子串的所有方案的LCP(w1,...,wk),LCP(w1,..,wk)表示字符串w1,...wk的最长公共前缀的长度,给定一个字符串Sl,r,G1中l=r,求出Fl,...Fr

思路:

z函数可以表示[i,n][1,n]的最长公共前缀,二分出最小的不能满足分成k段的最长公共前缀的长度,那么答案就是1,表示最大的分成k段的最长公共前缀的长度,对于二分的check来说,只要该位置的z[i]mid,就将[i,n]段分成[i,i+mid1][i+mid,n],这样保证分的子段数量最多

点击查看代码

1968G2

思路:

考虑二分的过程,是向后一位一位找到>=mid的位置然后来划分,如果能处理所有等于>=mid的z值的下标再二分找则效率更高,那么对于当前的能分的段数cnt,Fcnt=mid,因为要保存>=mid的z值下标,所以LCP从大到小枚举,而对于F来说,分的子段数量越大,LCP的值越小,所以将LCP从n枚举到1,记录Fcnt后,再用大的cnt更新小的cnt。

点击查看代码
posted @   Danc1ng  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示