显然全部相同的可以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