CF1555D Say No to Palindromes题解--zhengjun
题目大意
给你一个字符串,每次询问区间 [l,r][l,r][l,r] 最小需要改变几个才能使得这个区间的所有子区间都不是长度至少为 222 的回文串。
思路
首先我们想一想所有子区间都不是长度至少为 222 的回文串长什么样子。
- ai≠ai+1a_i\ne a_{i+1}ai=ai+1
- ai≠ai+2a_i\ne a_{i+2}ai=ai+2
这两个性质足够了。
所以这个串一定是形如 123123···
这样三个不同的字母组成的循环。
那么,对于每次询问,考虑枚举这个串的最终形式:
abcabc···
acbacb···
bacbac···
bcabca···
cabcab···
cbacba···
然后,要修改最少的步数变成这个目标串,可以看成算和这个目标串匹配的个数。
那么我们就可以把这三位分开处理,就只要询问一段区间中每隔三个是这个字符的数量就可以了,所以前缀和预处理递推一下就完事了。
最后要注意查询时区间前缀和左右端点是哪个减掉哪个就好了。
这个画个图就很直观的。
1 2 3 1 2 3 1 2 3
1 2 3 4 5 6 7 8 9i j
1 2 3 1 2 3 1 2 3
1 2 3 4 5 6 7 8 9i j
1 2 3 1 2 3 1 2 3
1 2 3 4 5 6 7 8 9i j
具体细节见代码。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
void read(){}
template<typename _Tp,typename... _Tps>
void read(_Tp &x,_Tps &...Ar){x=0;char c=getchar();bool flag=0;while(c<'0'||c>'9')flag|=(c=='-'),c=getchar();while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();if(flag)x=-x;read(Ar...);
}
const int N=2e5+10;
int n,m,cnt[3][N],a[N];
char c[N];
int min(int a,int b,int c,int d,int e,int f){if(b<a)a=b;if(c<a)a=c;if(d<a)a=d;if(e<a)a=e;if(f<a)a=f;return a;
}
int solve(int l,int r,int x,int y,int z){int k;x--;y--;z--;if((r-l+1)%3==0){//对区间长度模 3 分类讨论k=cnt[x][r-2]-cnt[x][l-3]+cnt[y][r-1]-cnt[y][l-2]+cnt[z][r]-cnt[z][l-1];//计算匹配数}else if((r-l+1)%3==1){k=cnt[x][r]-cnt[x][l-3]+cnt[y][r-2]-cnt[y][l-2]+cnt[z][r-1]-cnt[z][l-1];}else{k=cnt[x][r-1]-cnt[x][l-3]+cnt[y][r]-cnt[y][l-2]+cnt[z][r-2]-cnt[z][l-1];}return r-l+1-k;//修改的个数就是区间长度减去匹配的个数
}
int get(){int i,l,r;for(read(n,m),scanf("%s",c+1),i=1;i<=n;i++)a[i]=c[i]-'a';for(i=1;i<=3;i++)cnt[a[i]][i]=1;for(i=4;i<=n;i++)cnt[0][i]=cnt[0][i-3]+(a[i]==0),cnt[1][i]=cnt[1][i-3]+(a[i]==1),cnt[2][i]=cnt[2][i-3]+(a[i]==2);while(m--){read(l,r);if(l==r)printf("0\n");//这里一定要特判掉else printf("%d\n",min(solve(l,r,1,2,3),solve(l,r,1,3,2),solve(l,r,2,1,3),solve(l,r,2,3,1),solve(l,r,3,1,2),solve(l,r,3,2,1)));//枚举每一种情况}return 0;
}
int main(){return get();
}
谢谢–zhengjun
CF1555D Say No to Palindromes题解--zhengjun相关推荐
- cf1555D. Say No to Palindromes
cf1555D. Say No to Palindromes 题意: 给出一个字符串,长度为n,而且都是a,b,c三个字符构成的,然后有m个询问 每个询问给出l r,问要想这个区间内任意长度字串都不是 ...
- CF1553I Stairs题解--zhengjun
更好的阅读体验 题目传送门 Luogu,Codeforces 谈点其他的 这个题目翻译好像有亿点问题,我重新发一波. 给定一个长度为 nnn 的排列 ppp. 令其中第 iii 个位置的权值为最长的包 ...
- 洛谷P1046陶陶摘苹果题解--zhengjun
题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 101010 个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个 303030 厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳 ...
- 洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes 题解 C/C++
知识点: 回文数有两种 一种是单数位数,abcba,一种是双数位数,abccba 而双数位数是质数的只有11,即偶位回文数全不是质数除了11:所以不需要枚举到1亿,到1千万就好了 以下几种方法供参考 ...
- 洛谷P1053篝火晚会题解--zhengjun
题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了"小教官".在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有nnn个同学,编号从1 ...
- 洛谷P1039侦探推理题解--zhengjun
题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...
- 洛谷P1001题解--zhengjun
题目描述 输入两个整数 a,ba,ba,b,输出它们的和(∣a∣,∣b∣≤109|a|,|b |\le 10^9∣a∣,∣b∣≤109). 注意 PascalPascalPascal 使用intege ...
- 2020 NOI online 入门组第一题题解--zhengjun
题目描述 小明的班上共有 n n n 元班费,同学们准备使用班费集体购买 3 3 3 种物品: 圆规,每个 7 7 7 元. 笔,每支 4 4 4 元. 笔记本,每本 3 3 3 元. 小明负责订购文 ...
- 洛谷P1034矩形覆盖题解--zhengjun
题目描述 在平面上有 nnn 个点(n≤50n \le 50n≤50),每个点用一对整数坐标表示.例如:当 n=4n=4n=4 时,444 个点的坐标分另为:p1p_1p1(1,11,11,1),p ...
最新文章
- oracle中各种函数,oracle中常用函数大全
- CSS布局奇技淫巧:各种居中
- 大数据与web开发整合的最佳实践-思考
- SAP Analytics Cloud导入数据的规模限制
- Cell重磅综述:关于人类转录因子,你想知道的都在这
- 你知道荷兰旗问题吗?
- egg前面加什么,egg前加a还是an?
- 正则表达式之模式匹配的String方法
- 教你win10系统无法识别语音识别的解决方法
- 车辆路径问题(VRP)初探
- 左耳朵耗子的时间管理法则
- javaScript、PHP连接外卖小票机打印机方案(佳博、芯烨等)
- 浅谈显著性检测!真的很浅
- 节税指南|人才引进能节税?速教你掌握精髓!
- jQuery实现多选框的全选与反选
- 2021 ICPC Southeastern Europe Regional Contest 树上dfs+思维
- PHP纯手写正则爬取星座屋网站星座运势数据
- 不义联盟2充值php_DC也许醒过来了:谈谈《不义联盟2》和美漫IP改编手游
- springboot基础框架搭建
- Linux内核进程与线程