CF 2100-2400 strings 乱做

CF1995D Cases

显然如果选了某个字符那么不妨选它出现的所有位置。check 方式等价于相邻两个选择的位置间距 k,等价于连续 k 个必须选一个(最后一个必须选)

枚举位置维护字符集是做不了的,状态数 O(n2c) 无法优化

考虑枚举字符集 s。设原串连续 k 个字符的字符集为 ti,合法的 s 满足 sti。标记 Uti 及其子集,没有标记即为合法

时间复杂度 O(cn+2cc)

CF1980G Yasya and the Mysterious Tree

dis[u] 为根链边权异或

按套路用 trie 维护 dis 即可查询。注意查询前需要先删除自己
所有边异或 x 等价于给 dep 为奇数的 dis 异或 x,奇偶分别维护即可

CF1970D1 Arithmancy (Easy)

长度限制 30n,可以令长度分别 1,30,90,这样用本质不同子串数的大小就可以确定是哪两个串,只需要判断顺序

n=2 时容易构造出 OX O...O。顺着往下想,n=3 时可以增加一个前缀 O、后缀 X、中间随机的串

官方题解说直接随就行。。。

CF1968G2 Division + LCP (hard version)

注意到 lcp 一定是原串前缀,从小到大枚举长度 is[1:i] 下一次出现的位置为 min{j:jpz[j]i},并查集维护 z[]i 的位置。只会查找 O(nlnn)

官方题解是基于 lcpkn 的根号分治

CF1965C Folding Strip

注意到只要求所有折叠后对应位置相同,所以应该关注结果而不是过程

显然长度 >2 的连续段等价于长度 =1,2 的。感性理解:要让最终的长度尽量小就要让折叠次数尽量多,事实上可以再每个 =2 的连续段中间折一次,这样最终的串的 0/1 分别在奇/偶位置

实现

从左到右模拟折叠。维护方向 d,相对位置 j

int l = 0, r = 0;
	For(i,2,n, d = 1, j = 0) {
	if( s[i-1] == s[i] ) d *= -1;
	else j += d;
	ckmin(l, j), ckmax(r, j);
	}
	cout<<r-l+1<<'\n';

CF1930D2 Sum over all Substrings (Hard Version)

反过来考虑,qi=1 可以覆盖 pi1,pi,pi+1,可以从前往后贪心

sol 1

f[i,j] 表示覆盖了 [l,i],最后一个 1 位于 ij 的最小代价(j{0,1,2,3}

矩乘

sol 2

f[l,i] 表示覆盖了 [l,i] 的最小代价

f[l,i]={f[l,i3]+1,p[i]=1f[l,i1],p[i]=0

把右端点相同的合并计算,设 g[i]=lif[l,i]

g[i]={g[i3]+i,p[i]=1g[i1],p[i]=0

posted @   ft61  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示