【BZOJ】2084: [Poi2010]Antisymmetry

http://www.lydsy.com/JudgeOnline/problem.php?id=2084

题意:一个01串,求满足字符串0和1取反后,再将整个串反过来和原串一样的子串数目。(n<=500000)

#include <bits/stdc++.h>
using namespace std;
const int N=500005;
long long ans;
int len[N<<1], n;
char s[N<<1];
int main() {
	scanf("%d%s", &n, s+1);
	for(int i=n; i; --i) s[i<<1]=s[i], s[i<<1|1]='#';
	n=n<<1|1; s[1]='#';
	int cur=1;
	for(int i=2; i<=n; ++i) {
		int &now=len[i];
		now=min(len[(cur<<1)-i], max(0, cur+len[cur]-i));
		if(i&1) {
			while(i-now-1>=1 && i+now+1<=n && (s[i-now-1]=='#' || s[i-now-1]!=s[i+now+1])) ++now;
			ans+=now;
		}
		if(cur+len[cur]<i+now) cur=i;
	}
	printf("%lld\n", ans>>1ll);
	return 0;
}

  

发现就是0和1看做相等的回文串= =

妈呀发现在做manacher的时候有各种坑爹情况= =

首先要注意只能插入的特殊字符才能拓展= =否则如果是0或1拓展的话会出现莫名的问题= =(因为当0!=1的时候可能会造成类似这种

4
1001

答案应该是2

= =因为你会发现当'#'拓展后得到的长度,对于'0'或'1'在这个长度内不一定满足回文性= =

 

转载于:https://www.cnblogs.com/iwtwiioi/p/4350753.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值