Description

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

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

Input

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

Output

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

Sample Input

8

11001011

Sample Output

7

//7个反对称子串分别是:01(出现两次), 10(出现两次), 0101, 1100和001011​


Manacher,不多说……不过,怎么匹配呢?肯定不是直接匹配。我们将原串转换一下,把1改为2,0不变,中间添加1,那么我们匹配的时候就看看两个点是否相加等于2即可

统计答案?由于反对称子串一定是偶串,所以我们只要枚举1所在的位置。

那么答案是什么?p[i]/2。为什么?因为我们匹配的时候,是看两个点是否相加为2,那么匹配的两个点要么是1,要么是0和2。这样,回文半径每增加2,答案的个数就增加了1,所以直接累加 p[i]/2 即可。

初始值为1?整除把它干掉了……

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=5e5;
char s[N+10];
int val[N*2+10],p[N*2+10];
ll Ans;
int main(){
int len=read();
scanf("%s",s+1);
for (int i=1;i<=len;i++) val[i<<1]=s[i]-'0'?2:0,val[i<<1|1]=1;
len=len<<1|1;
val[1]=1,val[0]=val[len+1]=-1;
int Max=0,ID=0;
for (int i=1;i<=len;i++){
p[i]=Max>i?min(p[ID*2-i],Max-i):1;
while (val[i+p[i]]+val[i-p[i]]==2) p[i]++;
if (Max<p[i]+i-1) Max=p[ID=i]+i-1;
}
for (int i=1;i<=len;i+=2) Ans+=p[i]>>1;
printf("%lld\n",Ans);
return 0;
}

最新文章

  1. mount报错: you must specify the filesystem type
  2. SQL server 常用语句
  3. [经验] - JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案
  4. Spring MVC中Ajax实现二级联动
  5. .NET framework Chart组件SeriesChartType 枚举
  6. Java Integer类分析
  7. JAVA之数组查询binarySearch()方法详解
  8. C#中一个问号和两个问号(a ?? b)的作用
  9. 中文分词工具thulac4j正式发布
  10. UART通信
  11. XML Condition And
  12. MySQL 复制 - 性能与扩展性的基石 1:概述及其原理
  13. React学习笔记_01
  14. 启动apache 提示Starting httpd: AH00558
  15. [leet code 4] Median of Two Sorted Arrays
  16. js 正则学习小记之匹配字符串字面量
  17. 将*.sql数据库脚本导入到sqlserver中(sql文件导入sqlserver)
  18. delphi常用函数和方法
  19. 如何批量删除QQ浏览器指定历史记录和导出指定的历史记录
  20. 组件--Fragment(碎片)第二篇详解

热门文章

  1. Openwrt挂载NTFS硬盘提示“只读”错误的解决方法!
  2. iOS中MRC和ARC混编
  3. easyui英文提示变中文
  4. HDU 1272: 小希的迷宫(并查集)
  5. asp.net mvc的权限管理设计
  6. HDU 4786(最小生成树 kruskal)
  7. WebService(2)-XML系列之用Stax操作Xml
  8. mysql + Fluently NHibernate + WebAPI + Autofac
  9. 下面forward和redirect的描述,正确的是(ABCD)
  10. validationEngine验证的使用