题目描述

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

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

    下载解压 官方地址 wget https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.tar.gz tar -zxvf b ...

  2. 【刷题-LeetCode】306. Additive Number

    Additive Number Additive number is a string whose digits can form additive sequence. A valid additiv ...

  3. 【刷题-LeetCode】304. Range Sum Query 2D - Immutable

    Range Sum Query 2D - Immutable Given a 2D matrix matrix, find the sum of the elements inside the rec ...

  4. ps -ef aux区别

    第一点  -ef是System V展示风格,而aux是BSD风格.    BSD风格 字段含义:  USER:用户名称  PID:进程号  %CPU:进程占用CPU的百分比  %MEM:进程占用物理内 ...

  5. 前端HTML基础之form表单

    目录 一:form表单 1.form表单功能 2.表单元素 二:form表单搭建(注册页面) 1.编写input会出现黄色阴影问题 三:完整版,前端代码(注册页面) 四:type属性介绍 1.inpu ...

  6. CICD流程

    1.开发者git提交代码至gitlab仓库 2.jenkins从gitlab拉取代码,触发镜像构建 3.镜像上传至harbor私有仓库 4.镜像下载至执行机器--k8s node kubelet 5. ...

  7. JVM专题1: 类和类加载机制

    合集目录 JVM专题1: 类和类加载机制 Java对象的结构 在HotSpot虚拟机中, 对象在内存中存储的布局可以分为3块区域 对象头Header 实例数据Instance Data 对齐填充Pad ...

  8. 常见线程池之 newCacheThreadPool 缓存线程池 简单使用

    package com.aaa.threaddemo; import java.util.concurrent.BlockingQueue; import java.util.concurrent.E ...

  9. ApacheCN Python 译文集 20211108 更新

    Think Python 中文第二版 第一章 编程之路 第二章 变量,表达式,语句 第三章 函数 第四章 案例学习:交互设计 第五章 条件循环 第六章 有返回值的函数 第七章 迭代 第八章 字符串 第 ...

  10. ARC-124 部分题解

    E 直接统计原式不好做,注意到首先我们应该知道怎样的 \(x\) 序列是合法的,那么不妨首先来统计一下合法的 \(x\) 序列数量. 令 \(b_i\) 为 \(i\) 向右给的球数,那么有(\(i ...