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.
Example
For the input data:
8 11001011 the correct result is:
7 Antisymmetric fragments are: 01 (occurs twice), 10 (also twice), 0101, 1100, and 001011.
題目鏈接
題意:一個只含有0、1的字符串,這個字符串在將0變成1,將1變成0后進行反轉,如果和原來的字符串完全相同,則稱之為反對稱字符串,現在給你一個0、1的字符串,讓你求有多少個子字符串為反對稱字符串。
解題思路:因為經過0變1,1變0和反轉兩個操作,所以如果這個字符串的長度為奇數,它是不可能成為反對稱字符串的(因為最中間那個肯定不相同),對于一個長度為偶數且為l的字符串,我們只要讓它的第i個字符與第l-i+1(也就是倒數第i個字符)不相同即可,因此我們可以用manacher來解決這個問題。
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define maxn 500005using namespace std;typedef long long ll;ll n,ans,f[maxn*2],pos;char st[maxn],st1[maxn*2];bool fuhe(ll a,ll b){ if((st1[a]=='0'&&st1[b]=='1')||(st1[a]=='1'&&st1[b]=='0')||(st1[a]=='#'&&st1[b]=='#')) return true; return false;}int main(){ scanf("%lld",&n); scanf("%s",st); st1[0]='*'; for(ll i=0;i<n;i++){ st1[2*i+2]=st[i]; st1[2*i+1]='#'; } st1[2*n+1]='#'; ll l=strlen(st1),maxright=0; for(ll i=1;i<l;i++){ if(maxright>i) f[i]=min(f[2*pos-i],maxright-i); else f[i]=1; while(i-f[i]>=1&&i+f[i]<=l&&fuhe(i+f[i],i-f[i])) f[i]++; if(st1[i]=='#'&&i>1&&i<l){ //只有以#為中心的字符串才為偶數長 ans+=f[i]/2; if(i+f[i]>maxright){ maxright=i+f[i]; pos=i; } } }新聞熱點
疑難解答