BZOJ4236 JOIOJI

  前缀和后相当于查询三维空间某条直线,用两维坐标减去另一维就变成查询二维点了,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;
}
原文地址:https://www.cnblogs.com/Gloid/p/9830198.html