Description
Given a string with a length of n that contains only ′b′, ′c′, ′s′ three characters, find the longest contiguous substring so that the paragraph has either one or more characters, but no two characters appear the same number of times.
Input
The first line contains a positive integer, N (1<=n<=1000000), representing the length of the string.
The second line is a string of length n.
Output
Contains a row of a positive integer, the length of the longest substring that satisfies the condition.
Sample Input
9
Cbbssbcsc
Sample Output
6
Input Details
Select Bssbcs this substring.
When I first saw this problem, I thought of Usaco_2014_open_sliver's topic very naturally. If there are only two types of characters, then we can use the prefix and the thought, each character is represented as a ±1, so by prefix and additive, for the current position, only in the prefix and in the front to find the smallest position, and the current value of the prefix and transfer, time complexity O (NLOGN).
But the problem is not the same. It requires 22 of the elements within [l,r], so it is not possible to adopt the previous approach (but the prefix and the idea still apply). And for that reason, it's actually a three-dimensional problem if the problem is to be considered on three elements alone.
So according to Noip's request, we can not give up violence ah. The complexity of the violence is O (N2), which is clearly not over.
The last thing to do is to start from the metaphysical point of view:
First of all, if you use the general prefix and, we need to judge the following formulas: Sum′b′[i]−sum′b′[j]≠sum′c′[i]−sum′c′[j]
SUM′C′[I]−SUM′C′[J]≠SUM′S′[I]−SUM′S′[J]
SUM′S′[I]−SUM′S′[J]≠SUM′B′[I]−SUM′B′[J]
In order to get the conclusion I can transfer from J, it is obviously difficult at this time. The most convenient comparison is that the prefix and the above are converted to 3 attributes, or three fixed number, so that the comparison can only be judged by the i,j of the three attributes are not equal. Through the deformation of the above equation, we can get the following: Sum′b′[i]−sum′c′[i]≠sum′b′[j]−sum′c′[j] sum′c′[i]−sum′s′[i]≠sum′c′[j]−sum′s′[j] sum′S′[i] −SUM′B′[I]≠SUM′S′[J]−SUM′B′[J]
The same side of the content is the current position of three properties.
On this basis, we solve multidimensional problems, first of all, we should reduce the dimension.
We consider all the same a=sum′b′[i]−sum′c′[i] together to query and update, that is, do not let the elements between 22 to produce updates, so that the problem of a repeat is resolved, the complexity O (n) →o (NLOGN).
Then we have to drop one more dimension before it is good to operate. Due to the complexity of the problem, we will inevitably think of the use of data structure to optimize the above relationship. So we consider putting b=sum′c′[i]−sum′s′[i] in the subscript of the data structure. So long as in the data structure other nodes, find can update (C=sum′s′[i]−sum′b[i] unequal) POS, make abs (Pos-i) as large as possible.
For O (1) to query for possible maximum values within a node, we need to maintain the largest, second, minimum, and minor values on each node (the reason for maintaining the secondary value is to avoid the most significant C conflict with the current POS).
The subject is still a test of the Code Foundation, the code to achieve more difficult. (→_→)
Of course, see Code for concrete implementation. We need to maintain the situation between [1,pos-1] and [pos+1,end] separately, so the prefix tree array is implemented separately in the code. The practice of Claris large benniu is to reverse the B value so that all suffixes become prefixes to be updated.
#include <bits/stdc++.h> #define Clear (X,val) memset (x,val,sizeof (x)) using namespace Std;
static const int m=1000005;
int n,cnt[3];
Char Str[m]; struct Node{int a,b,c;}
NODE[M];
int head[m<<1],nxt[m]; void Add_edge (int val,int v) {nxt[v]=head[val],head[val]=v;} struct binary_tree{struct node{int mx1,mx2,mi1,m
I2;
Node () {mx1=mx2=mi1=mi2=-1;}
void Up (int val,int pos) {if (!~MI1) {Mi1=mx1=pos;return;}
if (Mi1>pos) {if (node[mi1].c!=val) mi2=mi1; mi1=pos; }else if (!~mi2| |
Mi2>pos) &&node[mi1].c!=val) Mi2=pos;
if (Mx1<pos) {if (node[mx1].c!=val) mx2=mx1; mx1=pos; }else if (!~mx2| |
Mx2<pos) &&node[mx1].c!=val) Mx2=pos;
}//Here the update implementation is more complex}bit[m<<1];
int Ask (node T,int pos) {int ans=0;
if (~T.MX1&&NODE[T.MX1].C!=NODE[POS].C) {if (ans<t.mx1-pos) Ans=t.mx1-pos; }else if (~t.mx2&&nodE[T.MX2].C!=NODE[POS].C) {if (ans<t.mx2-pos) Ans=t.mx2-pos;
} if (~T.MI1&&NODE[T.MI1].C!=NODE[POS].C) {if (ANS<POS-T.MI1) Ans=pos-t.mi1;
}else if (~t.mi2&&node[t.mi2].c!=node[pos].c) {if (ans<pos-t.mi2) ans=pos-t.mi2;
return ans; #define LOWBIT (x) x&-x void Pre_insert (int w,int pos) {while (w<m*2) {bit[w].up (node[p
Os].c,pos);
W+=lowbit (w);
} void Suf_insert (int w,int pos) {while (W) {bit[w].up (node[pos].c,pos);
W-=lowbit (w);
an int pre_query (int w,int pos) {int ans=0;
while (W) {Ans=max (Ans,ask (Bit[w],pos));
W-=lowbit (w);
}return ans;
int suf_query (int w,int pos) {int ans=0;
while (w<2*m) {Ans=max (Ans,ask (Bit[w],pos));
W+=lowbit (w);
}return ans;
}}pre,suf; int main (){scanf ("%d%s", &n,str+1);
Clear (Head,-1), clear (nxt,-1);
Node[0]= (node) {0,0,0};
Add_edge (node[0].a+m,0);
for (int i=1;i<=n;i++) {switch (Str[i]) {case ' B ': ++cnt[0];break;
Case ' C ': ++cnt[1];break;
Case ' S ': ++cnt[2];break;
} node[i]= (Node) {cnt[0]-cnt[1],cnt[1]-cnt[2],cnt[2]-cnt[0]};
Add_edge (Node[i].a+m,i);
int ans=0;
for (int i=1;i<m*2;i++) {for (int j=head[i];~j;j=nxt[j]) {int v1=pre.pre_query (NODE[J].B+M-1,J),
V2=suf.suf_query (NODE[J].B+M+1,J);
if (ANS<V1) ans=v1;
if (ANS<V2) ans=v2;
for (int j=head[i];~j;j=nxt[j]) {Pre.pre_insert (node[j].b+m,j);
Suf.suf_insert (NODE[J].B+M,J);
} int pre=0;
for (int i=1;i<=n+1;i++) if (Str[pre]!=str[i]) {Ans=max (ans,i-pre);
Pre=i;
printf ("%d\n", ans); }