题目描述

长度为偶数的回文串被称为偶回文串。如果一个字符串重新排序之后能够成为一个偶回文串,则称为可回文的。

给一个字符串,求可回文的子串个数。字符串只含小写字母,单个字符串长度不超过10^5,所有数据字符串长度之和不超过2*10^6。

时间限制:3000ms   内存限制:131072kb

解题思路

由于可以重新排序,所以一个子串只要任一字母出现偶数次即可。于是将字母编号,h(c) = ±1 << (c - 'a'),第奇数次出现为正,第偶数次出现为负。于是问题转化为求某一子区间的编号和为0,维护前缀和Sum[i],又把问题转化为求相同的前缀和的点。这个时候就发现问题非常简单了,直接把Sum排序就好了。如果有x个点的Sum值相同,则对应x*(x-1)/2个合法区间,从前往后扫描完排序后的Sum数组即可得到答案。

有个小技巧:Sum排序时多加入一个0,就不用特判整个串是不是可回文的。

时间复杂度:O(n logn)

附:c++代码

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5
6 using namespace std;
7 #define MaxLen 100020
8
9 typedef long long llt;
10 typedef unsigned long long ullt;
11
12 llt a[MaxLen], Sum[MaxLen];
13 char s[MaxLen];
14 bool vis[30];
15
16 int main()
17 {
18 //freopen("L.in", "r", stdin);
19 llt i, Len, pos;
20 ullt tmp, ans;
21 while(scanf("%s", s) != EOF)
22 {
23 memset(vis, false, sizeof(vis));
24 Len = strlen(s);
25 Sum[0] = 0;
26 for(i = 1; i <= Len; i++)
27 {
28 tmp = s[i - 1] - 'a';
29 if(vis[tmp])
30 {
31 a[i] = -(1 << tmp);
32 vis[tmp] = false;
33 }
34 else
35 {
36 a[i] = 1 << tmp;
37 vis[tmp] = true;
38 }
39 Sum[i] = Sum[i - 1] + a[i];
40 }
41 sort(Sum, Sum + Len + 1);
42 ans = 0;
43 for(i = 0; i <= Len; i++)
44 {
45 if(i == 0)
46 {
47 pos = 0;
48 continue;
49 }
50 if(Sum[i] != Sum[pos])
51 {
52 tmp = i - pos;
53 ans += tmp * (tmp - 1) / 2;
54 pos = i;
55 }
56 }
57 tmp = i - pos;
58 ans += tmp * (tmp - 1) / 2;
59 //ans += (i - pos) * (i - pos - 1) / 2;
60 //printf("%lld\n", ans);
61 cout << ans << endl;
62 }
63 return 0;
64 }

另一种思路

这是官方给出的题解。

任意一个子串里某个字符的出现次数可以被表示成两个前缀字符串里出现次数的差,例如abbababbabbab的子串ababba,就可以表示成abbababba和abb的差,如果这两个前缀串里任意一个字符出现的次数在模2意义下是相等的,那么他们的差对应的子串就是一个合法的解。 以第i个字符结尾的前缀串和以第i+1个字符结尾的前缀串只差一个字符,可以通过线性递推得到所有的前缀串的26个字符出现次数的奇偶性,可以发现每个前缀串对应26个不是0就是1的数字,可以将其压缩成一个二进制数字si,si的第k位对应第k个字符出现次数的奇偶性,添加一个字符可以利用二进制不进位加法,其中二进制不进位加法可以用异或(xor)来表示。

题目链接:https://biancheng.love/contest-ng/index.html#/29/problems

[题解]第十一届北航程序设计竞赛预赛——L.偶回文串的更多相关文章

  1. [题解]第十一届北航程序设计竞赛预赛——I.神奇宝贝大师

    题目描述 一张n*m的地图,每个格子里面有一定数量的神奇宝贝,求一个最优位置,使得所有神奇宝贝到该位置的曼哈顿距离最小. 一共有T组数据,每组数据包含两行,第一行是n和m(1<=n,m<= ...

  2. [题解]第十一届北航程序设计竞赛预赛——H.高中数学题

    题目描述 解题思路 可以求得通项公式:an = 2n + 1,所以问题就变成等差数列求异或和,这个具体为什么对我还不能很好地解释清楚,先挖坑吧. 附:c++代码 1 #include <iost ...

  3. [题解]第十一届北航程序设计竞赛预赛——F.序列

    题目描述 (1,--,n)的一个排列S,定义其对应的权值F[S]为:将S划分为若干段连续子序列,每个子序列都是上升序列,F[S]的值等于能划分出的最小段数. 求n的全排列的F[S]的和,答案mod(1 ...

  4. [题解]第十一届北航程序设计竞赛预赛——D.最大公约数

    题目描述 给一个长度为n(1<=n<=100000)的正整数列,分成尽量多的非空段,使得每一段的最大公约数相等.一个数的最大公约数是它本身. 解题思路 要求每一段子列的gcd相等,不妨设为 ...

  5. [题解]第十一届北航程序设计竞赛预赛——A.模式

    题目描述 输入一个学号,判断是计算机系or软件学院or其他院系. 解题思路 水题,直接判断or除以10000都可以.不废话,直接上代码. 1 #include <iostream> 2 # ...

  6. B P5 第十三届北航程序设计竞赛预赛

    https://buaacoding.cn/contest-ng/index.html#/188/problems 其实这题挺简单的. 注意到答案的大小最多是22 二分,check长度是mid的不同子 ...

  7. 小L的项链切割 (回文串)

    题目描述 小T送给了小L了一串项链.为了方便,我们把项链上形态不同钻石用不同的字母表示.这样小L的项链就变成了一个字符串.小L忽然想把这串项链优美地切割一下,她想把它切割成尽量少的回文项链,啊也就是回 ...

  8. 【题解】Luogu P4324 [JSOI2016]扭动的回文串

    原题传送门 这题实际挺水的 先对两个字符串分别跑马拉车 就能求出1.2类扭动回文串最大的长度 考虑第三类的扭动回文串\(S(i,j,k)\),一定可以表示为\(A(i,l)+A(l+1,j)+B(j, ...

  9. 【题解】APIO2014回文串

    哇哦~想不到我有生之年竟然能够做出字符串的题目ヾ(✿゚▽゚)ノ虽然这题比较裸但依然灰常开心! 首先有一个棒棒的性质:本质不同的回文串最多有 O(n) 个.首先 manacher 把它们都找出来,然后问 ...

随机推荐

  1. TextBox,RichTextBox设置行高

    /// <summary> /// 设置行距 /// </summary> /// <param name="ctl">控件</param ...

  2. 一次神奇的Azure speech to text rest api之旅

    错误Max retries exceeded with url: requests.exceptions.ConnectionError: HTTPSConnectionPool(host='%20e ...

  3. web前端基础之SCC(定位-z-index模态框)

    目录 一:定位(position) 1.relative(相对定位) 2.absolute(绝对定位) 3.fixed(固定) 二:相对定位 1.相对定位 2.实现相对定位 三:绝对定位 1.实现绝对 ...

  4. vue之keep-alive的使用

    keep-alive:是vue内置的一个组件,可以使被包含的组件保留状态或避免重新渲染.有两个生命周期函数:activated.deachtivated.在vue 2.1.0版本后新增了两个属性:in ...

  5. TensorFlow 机器学习秘籍中文第二版·翻译完成

    原文:TensorFlow Machine Learning Cookbook 协议:CC BY-NC-SA 4.0 不要担心自己的形象,只关心如何实现目标.--<原则>,生活原则 2.3 ...

  6. 双系统之删除Linux以及grub的引导

    问题阐述:最近玩双系统,把linux系统搞崩了,回到windos备份Linux系统的数据就把Linux的盘格式化了,然后再每当进入系统都会出现grub的命令格的窗口,输入任何命令都报错? 解决方法: ...

  7. (全局npmrc)nrm、npmrc、package-lock.json 的优先级

    npmrc 测试 nrm.npmrc 的优先级 实验 1. 没有设置 nrm. 默认设置 registry 为 https://registry.npmjs.org/ 下载的所有包都是通过以上域名获取 ...

  8. php程序员经验

    PHP 学习计划流程2008-10-22 17:23PHP 学习计划流程1.看教程 (2-3月)大概1天1个章节,比如<PHP圣经>有32章,1个多月就看完了,当然后面的章节每章1天肯定看 ...

  9. Java使用DOM方式读写XML

    一.DOM读取 import ***; public class ReadXML { public static void main(String[] args) { try { //DOM Docu ...

  10. 简介GitHub的使用方法--管理个人代码

    转自 http://blog.csdn.net/tengyeyijiu/article/details/46446283git是一个分布式版本控制系统,最初由linus torvalds编写,用作Li ...