前缀和后相当于查询三维空间某条直线,用两维坐标减去另一维就变成查询二维点了,map即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<map> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 200010 int n,a[N],b[N],c[N],ans; map<int,int> f[N*2]; int main() { #ifndef ONLINE_JUDGE freopen("bzoj4236.in","r",stdin); freopen("bzoj4236.out","w",stdout); const char LL[]="%I64d "; #else const char LL[]="%lld "; #endif n=read();char ch=getchar();while (ch<'A'||ch>'Z') ch=getchar(); for (int i=1;i<=n;i++) { a[i]=a[i-1],b[i]=b[i-1],c[i]=c[i-1]; if (ch=='J') a[i]++; if (ch=='O') b[i]++; if (ch=='I') c[i]++; ch=getchar(); } for (int i=1;i<=n;i++) { a[i]-=c[i],b[i]-=c[i]; if (a[i]==0&&b[i]==0) ans=i; else if (f[a[i]+n].find(b[i])!=f[a[i]+n].end()) ans=max(ans,i-f[a[i]+n][b[i]]); else f[a[i]+n][b[i]]=i; } cout<<ans; return 0; }