您的位置:首页 > 其它

SPOJ STC02 Antisymmetry——马拉车啊马拉车

2017-02-23 23:21 176 查看
Antisymmetry

Description

Byteasar studies certain strings of zeroes and ones. Let S be such a string. By Sr we will denote the reversed (i.e., “read backwards”) string S, and by SI we will denote the string obtained from S by changing all the zeroes to ones and ones to zeroes.

Byteasar is interested in antisymmetry, while all things symmetric bore him. Antisymmetry however is not a mere lack of symmetry. We will say that a (nonempty) string S is antisymmetric if, for every position i in S, the i-th last character is different than the i-th (first) character. In particular, a string S consisting of zeroes and ones is antisymmetric if and only if S=SIr. For example, the strings 00001111 and 010101 are antisymmetric, while 1001 is not.

In a given string consisting of zeroes and ones we would like to determine the number of contiguous nonempty antisymmetric fragments. Different fragments corresponding to the same substrings should be counted multiple times.

Input

The first line of the standard input contains an integer N (1 <= N <= 500000) that denotes the length of the string. The second line gives a string of 0 and/or 1 of length N. There are no spaces in the string.

Output

The first and only line of the standard output should contain a single integer, namely the number of contiguous (non empty) fragments of the given string that are antisymmetric.

For the input data:

8

11001011

the correct result is:

7

首先你要会马拉车马拉车啊,马拉车——Manacher 算法

我们定义这样另类的回文字串:如果左侧取反等于右侧,则回文

这个题就是算有多少个另类的回文字串

在计算的时候,依旧是插入’#’但是在判断左右是否相等时:

1:如果左侧某个字符是’#’那么右侧相应字符也应该是’#’才算相等

2:如果左侧某个字符是数字1或者0,那么右侧应该是左侧取反才算相等

这样就按照马拉车的算法进行计算:但是当以数字为中心时,相应的值直接等于0

假如开了数组mp[i]存的是i为对称轴的最长回文字串,那么i为对称轴的回文字串个数=mp[i]

代码

//============================================================================
// Name        : test.cpp
// Author      : Qihan
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <bits/stdc++.h>
#define pi acos(-1.0)
using namespace std;
typedef long long int LLI;
typedef pair<LLI,LLI> PII;
#define Lowbit(x) (x & (-x))
const int inf = 0x3f3f3f;
const int maxn = (500000 + 10);

char Ma[maxn * 2];
LLI mp[maxn * 2];

bool Judge(int i) {
if(Ma[i + mp[i]] == '#' && Ma[i + mp[i]] == '#')    return true;
if(Ma[i + mp[i]] == '0' && Ma[i - mp[i]] == '1')    return true;
if(Ma[i + mp[i]] == '1' && Ma[i - mp[i]] == '0')    return true;
return false;
}

void Manacher(char *s,int len) {
int l = 0;
Ma[l ++] = '$';
Ma[l ++] = '#';
for(int i = 0; i < len; i ++) {
Ma[l ++] = s[i];
Ma[l ++] = '#';
}
Ma[l] = '\0';
LLI mx = 0,id = 0;
for(int i = 0; i < l; i ++) {
if(i % 2 == 0)  mp[i] = 0;
else   mp[i] = mx > i ? min(mp[2 * id - i],mx - i) : 1;
while(Judge(i)) mp[i]++;
if(i + mp[i] > mx) {
mx = i + mp[i] - 1;
id = i;
}
}
}

char str[maxn];

int main() {
//    freopen("/home/qihan/Documents/in","r",stdin);
int n;
scanf("%d",&n);
scanf("%s",str);
Manacher(str,n);
LLI ans = 0;
for(int i = 1; i < n * 2 + 2; i += 2) {
ans += (mp[i] - 1) / 2;
}
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Manacher 字符串