题目大意

对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串。比如00001111和010101就是反对称的,1001就不是。

现在给出一个长度为N的01字符串,求它有多少个子串是反对称的。

输入样例

第一行一个正整数N (N ≤ 500,000)。第二行一个长度为N的01字符串。

输出样例

一个正整数,表示反对称子串的个数。

输入样例

8

11001011

输出样例

7

题解

最简单的方法就是二分+Hash了。

我们可以想,对于每个点$i$,如果字符串$[i - j + 1...i + j]$为反对称的,则对于满足$1 \leqslant k < j$的$k$,都有字符串$[i - k + 1...i + k]$为反对称的。

根据这个单调性,我们只需要枚举$i$,然后二分$j$即可。

#include <iostream>
#include <cstdio> #define MAX_N (500000 + 5) using namespace std; typedef unsigned long long ull;
typedef const unsigned long long cull;
int n;
char s[MAX_N];
cull b = ;
ull h1[MAX_N], h2[MAX_N], pb[MAX_N];
int ans; int main()
{
scanf("%d%s", &n, s + );
pb[] = ;
for(register int i = , j = n; i <= n; ++i, --j)
{
h1[i] = h1[i - ] * b + (s[i] == '') + ;
h2[j] = h2[j + ] * b + (s[j] == '') + ;
pb[i] = pb[i - ] * b;
}
int lt, rt, mid;
for(register int i = ; i <= n; ++i)
{
lt = ;
rt = min(i, n - i);
while(lt <= rt)
{
mid = lt + rt >> ;
if(h1[i + mid] - h1[i - mid] * pb[mid << ] != h2[i - mid + ] - h2[i + mid + ] * pb[mid << ]) rt = mid - ;
else lt = mid + ;
}
ans += rt;
}
printf("%d", ans);
return ;
}

参考程序(Hash)

当然,我们也可以直接用manacher做。

其实反对称就类似回文,这里的反对称其实可以理解为对于每个字符串,左半边异或后等于右半边,我们把manacher稍微改一下即可。

注意,这里不能随枚举奇数长度的子串,因为奇数长度本身就是不可能反对称的,这样子可能会影响偶数长度子串的判断。

#include <iostream>
#include <cstdio> #define MAX_N (500000 + 5) using namespace std; int n;
char s[MAX_N];
int len;
char ns[MAX_N << ];
int p[MAX_N << ];
char to[];
long long ans; int main()
{
scanf("%d%s", &n, s + );
len = n << | ;
ns[] = '~';
ns[len + ] = '^';
ns[] = '#';
for(register int i = ; i <= n; ++i)
{
ns[i << ] = s[i];
ns[i << | ] = '#';
}
to[''] = '';
to[''] = '';
to['#'] = '#';
to['~'] = '~';
to['^'] = '^';
int rt = , mid = ;
for(register int i = ; i <= len; i += )
{
if(i < rt) p[i] = min(rt - i + , p[(mid << ) - i]);
else p[i] = ;
while(ns[i + p[i]] == to[ns[i - p[i]]]) ++p[i];
if(i + p[i] - > rt)
{
rt = i + p[i] - ;
mid = i;
}
ans += p[i] >> ;
}
printf("%lld", ans);
return ;
}

参考程序(Manacher)

【题解】Antisymmetry的更多相关文章

  1. BZOJ2084: [Poi2010]Antisymmetry

    2084: [Poi2010]Antisymmetry Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 187  Solved: 125[Submit] ...

  2. 【BZOJ2084】[Poi2010]Antisymmetry(manarcher)

    [BZOJ2084][Poi2010]Antisymmetry(manarcher) 题面 BZOJ 洛谷 题解 一眼马拉车吧...明显就是在回文串的基础上随便改了改. 似乎还可以魔改回文树,然而我这 ...

  3. POI2010题解

    POI2010题解 我也不知道我为什么就开始刷POI了 有些题目咕掉了所以不完整(我都不知道POI到底有多少题) [BZOJ2079][Poi2010]Guilds (貌似bz跟洛谷上的不是一个题?) ...

  4. 【bzoj2084】[Poi2010]Antisymmetry

    2084: [Poi2010]Antisymmetry Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1205  Solved: 756[Submit ...

  5. bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)

    bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...

  6. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  7. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  8. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  9. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

随机推荐

  1. 使用 Struts2 校验器校验用户注册信息的例子

    转自:https://blog.csdn.net/jin2005006/article/details/53999562 基于验证框架的输入校验 一.创建一个struts2项目testValidato ...

  2. elasticsearch 基础 —— Field Collapsing字段折叠

    允许根据字段值折叠搜索结果.通过按折叠键选择顶部排序文档来完成折叠.例如,下面的查询检索每个用户的最佳推文,并按喜欢的数量对它们进行排序. GET /twitter/_search { "q ...

  3. Nginx学习总结:geo与image模块(四

    斜体下划线,表示建议采用默认配置,无需显式的配置 一.ngx_http_geo_module 核心特性为:根据客户端IP(段),geo模块将会匹配出指定的变量(比如,国家代码,城市代码).geo模块可 ...

  4. Linux学习之旅(二)Linux文档操作

    目录操作 1. 创建目录 // 目录可以是绝对路径,也可以是相对路径 mkdir 目录名 //创建一个目录 mkdir -p 目录名1/目录名1/... //一次性创建多级目录 2. 删除目录 // ...

  5. SQL回顾1

    1.学生表Student(SID,Sname,Sage,Ssex) --SID 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 2.课程表 Course(CID,Cname,T ...

  6. BZOJ5261 Rhyme

    传送门 广义后缀自动机= =+ 跟ptx大爷的博客学的 戳我传送 我写的第一种 建立Trie树的写法 bfs建立SAM 为什么是bfs呢 我也不知道(GG) 经过我一番抱大腿+询问 各位大爷说的原因是 ...

  7. nyoj 253:LK的旅行 【旋转卡壳入门】

    题目链接 求平面最大点对. 找凸包 -> 根据凸包运用旋转卡壳算法求最大点对(套用kuang巨模板) 关于旋转卡壳算法 #include<bits/stdc++.h> using n ...

  8. 【leetcode】592. Fraction Addition and Subtraction

    题目如下: 解题思路:本题考察的是分数的加减法.小学时候就学过,分数的加减法是先求两个分母的最小公倍数,然后分子分别乘以最小公倍数与自己分母的商,相加后约分即可.所以,本题只要按+,-两个符号分割输入 ...

  9. php ord()函数 语法

    php ord()函数 语法 作用:返回字符串的首个字符的 ASCII 值.直线电机生产厂家 语法:ord(string) 参数: 参数 描述 string 必须,要从中获得ASCII值的字符串 说明 ...

  10. 【CF906E】Reverses(回文自动机,最小回文分割)

    题意:给定两个长度相等的仅由小写字母组成的串A和B,问在A中最少选择多少段互不相交的子串进行翻转能使A和B相同 len<=5e5 思路:构造新串S=a[1]b[1]a[2]b[2]...a[n] ...