显然全部相同的可以O(N)扫一遍得到,那么不妨考虑不存在某两种字母相同的最长长度。
令x[i]为1~i中‘B’的个数,y[i]为'C'的个数,z[i]为‘S’的个数。那么某一段i+1~j,不符合题设的条件为:
x[i]-x[j]=y[i]-y[j]或x[i]-x[j]=z[i]-z[j]或y[i]-y[j]=z[i]-z[j]。
如果把与i相关的移到一边,然后每个点相当于一个三元组(x[i]-y[i],y[i]-z[i],z[i]-x[i]),然后如果一对u,v(u<v),使得三元组的每一个元素两两不同,那么就用v-u更新答案。
第一维排序;然后以第二维为下标维护树状数组,存储最大值,最大值的第三维;和最大值的第三维不同的最大值。还有最小值。
实际上可以不用树状数组,直接整体二分也可以。
时间复杂度O(NlogN)。注意常数。
AC代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 1000000000
#define N 1000005
using namespace std;
int n,cnt,ans,tot,fst[N<<1],pnt[N],nxt[N]; struct node{ int x,y,z,id; }a[N],c[N][2];
bool cmpx(node u,node v){ return u.x<v.x; }
bool cmpy(node u,node v){ return u.y<v.y; }
void add(int x,int y){
pnt[++tot]=y; nxt[tot]=fst[x]; fst[x]=tot;
}
void dn(node &u,int x,int y){
if (x<u.x){
if (y==u.y) u.x=x; else{ u.z=u.x; u.x=x; u.y=y; }
} else if (y!=u.y) u.z=min(u.z,x);
}
void up(node &u,int x,int y){
if (x>u.x){
if (y==u.y) u.x=x; else{ u.z=u.x; u.x=x; u.y=y; }
} else if (y!=u.y) u.z=max(u.z,x);
}
void qry(int x,int k,int y){
for (; x; x-=x&-x){
if (c[x][0].y==y) ans=max(ans,k-c[x][0].z); else ans=max(ans,k-c[x][0].x);
if (c[x][1].y==y) ans=max(ans,c[x][1].z-k); else ans=max(ans,c[x][1].x-k);
}
}
void mdy(int x,int k,int y){
for (; x<=cnt; x+=x&-x){
dn(c[x][0],k,y); up(c[x][1],k,y);
}
}
void solve(){
int i,j,k;
for (i=1; i<=cnt; i++){
c[i][0].x=c[i][0].z=inf; c[i][1].x=c[i][1].z=-inf;
}
for (i=1; i<=(n<<1|1); i++){
for (j=fst[i]; j; j=nxt[j]){
k=pnt[j]; qry(a[k].y-1,a[k].id,a[k].z);
}
for (j=fst[i]; j; j=nxt[j]){
k=pnt[j]; mdy(a[k].y,a[k].id,a[k].z);
}
}
}
int main(){
scanf("%d",&n); int i,p,t=0;
char ch=getchar(),lastch='A';
while (ch<'A' || ch>'Z') ch=getchar();
for (i=1; i<=n; i++){
if (ch==lastch) t++; else t=1; ans=max(ans,t);
a[i]=a[i-1]; a[i].id=i;
if (ch=='B'){ a[i].x++; a[i].z--; } else
if (ch=='C'){ a[i].y++; a[i].x--;} else{ a[i].z++; a[i].y--; }
if (i<n){ lastch=ch; ch=getchar(); }
}
for (i=0; i<=n; i++) add(a[i].y+n+1,i);
for (i=1; i<=(n<<1|1); i++) if (fst[i]){
cnt++;
for (p=fst[i]; p; p=nxt[p]) a[pnt[p]].y=cnt;
}
tot=0; memset(fst,0,sizeof(fst));
for (i=0; i<=n; i++) add(a[i].x+n+1,i);
solve();
for (i=0; i<=n; i++) a[i].y=cnt-a[i].y+1;
solve();
printf("%d\n",ans);
return 0;
}
by lych
2-16.4.2