首页 > 其他分享 >CF1555D题解

CF1555D题解

时间:2023-10-25 19:35:09浏览次数:27  
标签:字符 CF1555D int 题解 循环 长度 回文 neq

  • 分析

    注意到字符集大小很小,那么很容易就会产生回文,那么合法序列的种类就会比较有限。
    思考对于不同长度而言合法序列的种类,显然长度为 \(1\) 时无回文,长度为 \(2\) 只要两个字符不同就无回文。
    尝试扩展到长度为 \(3\) 时的情况,显然 \(s_1 \neq s_2\),\(s_2 \neq s_3\)。发现 \(s_1 = s_3\) 时会产生形如aba的回文,所以 \(s1 \neq s3\),那么当长度为 \(3\) 时,需要三个字符互不相同才没有回文。
    继续向下扩展。当长度为 \(4\) 时,有 \(s_4 \neq s_3\),\(s_4 \neq s_2\),由于字符集的大小为 \(3\),那么 \(s_4 = s_1\),这样一直推到 \(s_6\) 发现 \(s_1 = s_4\),\(s_2 = s_5\),\(s_3 = s_6\),以此类推,对于一个长度为 \(n\) 的合法子串,其一定是由长度为 \(3\) 且 \(3\) 个字符互不相同的循环节循环而成的。

    思考如何求最小修改,对于一个子串,我们要求的就是与之最相似的的合法子串与这个串中不同的字符个数(定义不同的字符个数越小越相似)。
    思考求最相似合法子串的循环节以及循环起点。发现循环起点并不重要,因为错开一位可以看做将第 \(1\) 个字符放到了最后一位。
    思考求循环节,发现循环节一共有 \(3!=6\) 种情况,于是可以枚举循环节,然后求最小的字符个数。

    这样的时间复杂度是 \(\mathcal{O(nm)}\) 的,需要进行优化。
    发现对于同一个循环节,不同的字符个数满足可加性,那么对于每个循环节,预处理出字符串中每个位置的不同字符个数的前缀数组,在每次询问的时候就可以通过减去两个前缀快速求出不同字符个数,将时间复杂度降到 \(\mathcal{O(n + m)}\),可以通过本题。

  • 代码

#include <iostream>
using namespace std;
constexpr int MAXN(1000007);
constexpr int INF(0x3f3f3f3f);
int f[7][MAXN];
string a[7] = {"#", "abc", "acb", "bac", "bca", "cab", "cba"};
string s;
int n, q;
inline void read(int &temp) { cin >> temp; }
inline int calc(int l, int r) {
	read(l), read(r);
	int cnt(INF);
	for (int i(1); i <= 6; ++i)  cnt = min(cnt, f[i][r - 1] - f[i][l - 2]);
	return cnt;
}
int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	read(n), read(q);
	cin >> s;
	for (int i(1); i <= 6; ++i)
		for (int j(0); j < (int)s.length(); ++j)  f[i][j] = f[i][j - 1] + (s[j] != a[i][j % 3]);
	for (int i(1), l(0), r(0); i <= q; ++i)  cout << calc(l, r) << endl;
	return 0;
}

标签:字符,CF1555D,int,题解,循环,长度,回文,neq
From: https://www.cnblogs.com/Kazdale/p/17787955.html

相关文章

  • P9669 [ICPC2022 Jinan R] DFS Order 2 题解
    P9669[ICPC2022JinanR]DFSOrder2题解简要题意给定一棵\(n\)个节点的树,根节点是\(1\)。从根节点开始深度优先搜索这一棵树,dfs序是在搜索过程中访问节点的顺序。对于每一个节点\(v\),你要给出有多少种不同的dfs序,使得\(v\)出现在第\(j\)个位置。答案对\(99824......
  • P9769 HUSTFC 2023 简单的加法乘法计算题 题解
    动态规划#单调队列Question给出一个\(x=0\)通过一些操作把\(x\)变成\(y\)。有两个集合\(A,B\)。\(A\)包含了\(n\)个元素,分别是\(1-n\)的所有正整数,集合\(B\)给出\(m\)个元素,可以进行一下函数选择\(A\)中的一个元素\(a\),令\(x\)加上\(a\)选择\(B\)......
  • CF1555B题解
    分析放桌子有两种放法,一种是上下放,一种是左右放,分别计算最小值取\(\min\)即可。注意到原题使用的是平面直角坐标系,于是将原图顺时针旋转\(90^{\circ}\),将下标表示方式与代码中下标的表示方式统一,相应的,左下角和右上角也变成了左上角和右下角。代码#include<iostream......
  • Kettle链接SqlServer+Jdk8 问题解决
     这两天要弄个ldap对接,客户端server2016,数据库那边winserver2008,数据库也是2008最开是链接出现类似这样的,更换了链接mssql的Jar版本,从12换到了6的老版本,没用。  后来更改网上提示的  C:\ProgramFiles\Java\jre-1.8\lib\security\java.security文件jdk.tls.......
  • B1024 题解
    本着10月杂题题解只记重量级的原则,再加上这个系列好久没更新了,搞一发。原题链接发挥还可以的一场,至少比csp-s发挥的好。T1智慧概率题,考场差点出来,30pts。T2简单计数题,之前几场都卡T2,终于出来一次,100pts。T3简单数据结构题,打的30pts暴力,但是有50pts。T4智慧......
  • CF1572F Stations 题解-Segment Tree Beats
    20231025CF1572FStations题解-SegmentTreeBeats吉司机线段树好题!!!CF3400。传送门Statement有\(n\)个广播站,第\(i\)个广播站高度为\(h_i\),范围为\(w_i\)。初始\(h_i=0,w_i=i\)。广播站\(i\)能向广播站\(j\)传递消息,当且仅当\(i\lej\lew_i\),且\(h_i>\max\lim......
  • 恨7不成妻题解
    恨7不成妻题解分析数位\(DP\)考虑题目中的两个条件,每一位不等于\(7\)直接枚举时把\(7\)排除,其他两种情况直接放在状态里。因为题目要求平方和,我们考虑每次加上一位(设加入的是第\(i\)位)时会发生什么设原平方和为\[\sum_{k=1}^ta_k^2\]加入一位\(p\)之后每个数......
  • P9771 HUSTFC 2023 排列排序问题 题解
    Question给出一个\(N\)个元素的排序\(a\),我们可以对排列进行一些操作将这个排列切割成若干个序列将其中一些序列翻转将这些序列连接起来得到一个新的排列需要让最后的排列有序Solution这个题的描述有点小问题理解应该是切一次,然后再反转合并,不可能会先合并再切再反转......
  • P9744 「KDOI-06-S」消除序列 题解
    @目录DesciptionSolutionCodeDesciption给定一个长度为\(i\)的序列\(v_1,v_2,\dots,v_n\),初始时所有元素的值都为\(1\)。对于下标\(i\)有\(3\)种操作:将\(v_1,v_2,\dots,v_i\)的值变为\(0\),费用是\(a_i\)。将\(v_i\)的值变为\(0\),费用是\(b_i\)。将\(v_i\)......
  • Meta Hacker Cup 2023 Round 1 题解
    ProblemA:HereComesSantaClaus给一个数列,要求分成若干组,要求每组至少2个数,使得所有组中位数的最大值与最小值之差尽量大,求这个值。#include<bits/stdc++.h>usingnamespacestd;#defineFor(i,n)for(inti=1;i<=n;i++)#defineFork(i,k,n)for(inti=k;i<=n;i++)#define......