bzoj 4236: JOIOJI map+乱搞

来源:互联网 发布:微信拼团软件 编辑:程序博客网 时间:2024/05/16 18:18

题意

JOIOJI桑是JOI君的叔叔。“JOIOJI”这个名字是由“J、O、I”三个字母各两个构成的。
最近,JOIOJI桑有了一个孩子。JOIOJI桑想让自己孩子的名字和自己一样由“J、O、I”三个字母构成,并且想让“J、O、I”三个字母的出现次数恰好相同。
JOIOJI桑家有一份祖传的卷轴,上面写着一首长诗,长度为N,由“J、O、I”三个字母组成。JOIOJIさん想用诗中最长的满足要求的连续子串作为孩子的名字。
现在JOIOJI桑将这首长诗交给了你,请你求出诗中最长的、包含同样数目的“J、O、I”三个字母的连续子串。
1<=N<=2*10^5

分析

s1表示J的前缀和,s2表示O的,s3表示I的。
然后每次把(s1-s2,s2-s3)在map里面找一下就好了。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<map>using namespace std;map<pair<int,int>,int> w;int n;char s[200005];int main(){    scanf("%d",&n);    scanf("%s",s+2);    int s1=0,s2=0,s3=0,ans=0;    w[make_pair(0,0)]=1;    for (int i=2;i<=n+1;i++)    {        if (s[i]=='J') s1++;        else if (s[i]=='O') s2++;        else s3++;        int x=w[make_pair(s2-s1,s3-s2)];        if (!x) w[make_pair(s2-s1,s3-s2)]=i;        else ans=max(ans,i-x);    }    printf("%d",ans);    return 0;}