题目描述

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

给一个字符串,求可回文的子串个数。字符串只含小写字母,单个字符串长度不超过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 }

View Code

另一种思路

这是官方给出的题解。

任意一个子串里某个字符的出现次数可以被表示成两个前缀字符串里出现次数的差,例如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

转载于:https://www.cnblogs.com/CQBZOIer-zyy/p/5049661.html

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

  1. PAT甲级1136 A Delayed Palindrome :[C++题解]回文串和高精度并输出过程

    文章目录 题目分析 题目链接 题目分析 此题和PAT甲级1024 Palindromic Number:[C++题解]回文串和高精度加法 一样.区别是多了输出整个计算过程. 下面是主要知识点. 一个判 ...

  2. leetcode题解132-分割回文串 II

    问题描述 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文. 返回符合要求的 最少分割次数 . 示例 1: 输入:s = "aab" 输出:1 解释:只需一次分割 ...

  3. leetcode题解131-分割回文串

    问题描述 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 .返回 s 所有可能的分割方案. 回文串 是正着读和反着读都一样的字符串. 示例 1: 输入:s = "aa ...

  4. BZOJ4755: [JSOI2016]扭动的回文串——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4755 JYY有两个长度均为N的字符串A和B. 一个"扭动字符串S(i,j,k)由A中的第 ...

  5. 2016年首届南航-河海联合程序设计竞赛暨第十一届南航程序设计竞赛 题解

    问题 A: Unhappy sion 时间限制: 1 Sec  内存限制: 128 MB 提交: 335  解决: 153 [提交][状态][讨论版] 题目描述 After 2rd ccpc,UNCL ...

  6. C语言程序设计之判断是否是回文数

    给出一个相对可靠的定义: 设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数. 例如,若n=1234321,则称n为一回文数:但若n=1234567,则n不是回文数. ...

  7. 第十二届北航程序设计竞赛初赛——勾肥大战题解

    本题中假定了屠夫不会影响友方单位的肉钩,所以我们可以对每个己方屠夫单独考虑.对己方屠夫aa,敌方屠夫bb,如果aa能钩到bb,那么被钩的地方CC与a.ba.b初始位置A.BA.B会形成一个三角形ABC ...

  8. “华为杯”山东理工大学第十一届ACM程序设计竞赛(正式赛)

    猜先 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 小 A 和小 B 最近开始学习下 ...

  9. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛——L题 建立火车站

    题目描述 新冠疫情,导致了各个城市之间物资输送的障碍.假设有N个城市在一条直线上,为了物资能顺利抵达各个城市,可以在路线上建立最多个数为K个暂时停靠站,由于火车在两个站台(城市也算站台)之间的距离越近 ...

最新文章

  1. DELPHI实现游戏内存的修改
  2. 一、Go语言环境搭建
  3. GitHub 标星 8w!学完这份指南后,你就可以去 Google 面试了!
  4. leetcode 剑指 Offer 05. 替换空格
  5. php点链接直接现在文件吗,PHP实现点击a标签的href做链接时,直接保存文件(任何类型),而...
  6. web入门,这些必须掌握!!!
  7. Android View框架总结(九)KeyEvent事件分发机制
  8. 如何巧妙应对压力面试
  9. 我行我素购物管理系统
  10. 为什么越受重视的游戏项目越难开发好!
  11. MySQL 8.0 不能被远程连接的解决办法及修改密码、创建用户、授予所有权
  12. Skyler2003的资源QwQ
  13. android 打开网络设置 异常,逍遥安卓模拟器显示网络异常,请查收最完整的解决方法...
  14. foxmail 总是提示QQ 邮箱需要输入密码
  15. Python数据拟合幂函数y=ax^b
  16. python中的圆周率怎么表示_如何采用Python语言求解圆周率的π值
  17. 松耦合式的权限控制设计,自定义权限表达式
  18. PL0功能扩充(浮点数,数组,数组加减乘除等)
  19. 波导Z769手机java下载_手机指令秘籍传授
  20. SQL Server 数据库实验课第九周——第六章总结

热门文章

  1. windows或Ubuntu中请求github.com请求超时,或在下载GitHub文件出现:<urlopen error [Errno 110] Connection timed out>
  2. codechef INSQ15_A(hash+二分)
  3. redis中的ziplist
  4. springmvc中的类型转换器
  5. unity shader 纹理透明效果
  6. 细胞膜内流体应力分析
  7. Shell脚本——初识
  8. python的__init__几种方法总结【转载】
  9. 俄罗斯最新开源的牛掰数据库ClickHouse
  10. virtualBox使用nat模式下ssh连接