4236: JOIOJI 思路题 map

来源:互联网 发布:手机电子狗软件那个准 编辑:程序博客网 时间:2024/05/17 07:13

一开始sb了写的hash+二分,后来突然反应过来这个答案根本不能二分啊QAQ。
因为答案为len,长度小于len的并不一定满足QAQ,我真是sb。
其实想到二分是看着范围感觉是NlogN的。。于是瞎想了一下就写了。。于是我就开始想线性的做法。
(我突然想起来ws_yzy大神跟我说这题的代码很短?)。
于是又想了一会QAQ。。
我们要求的是一个区间L,R中,三种字符的出现次数相等,那么似乎要维护前缀和的样子?
我们分别用三个变量cnt1,cnt2,cnt3表示这个区间内JOI出现的次数,转化为前缀和的形式:sum1[R]-sum1[L-1]==sum2[R]-sum2[L-1]==sum3[R]-sum3[L-1]。
似乎还是不可做啊卧槽。。。
咦如果是线性的话,R和L应该分开想啊。。于是移项:
sum1[R]-sum2[R]==sum1[L-1]-sum2[L-1],
sum2[R]-sum3[R]==sum2[L-1]-sum3[L-1]。
好像可做了?只要看看当前状态有没有之前对应的状态?
嗯。。果断想到map。。解决了。。QAQ。

#include<bits/stdc++.h>using namespace std;char s[200005];map <pair<int,int>,int> mp;int cnt1,cnt2,cnt3,n,ans;int main(){    scanf("%d",&n);    scanf("%s",s+1);    mp[make_pair(0,0)]=0;    for (int i=1;i<=n;i++)    {        switch(s[i])        {            case 'J':                cnt1++;                break;            case 'O':                cnt2++;                break;            case 'I':                cnt3++;                break;        }        if (mp.find(make_pair(cnt1-cnt2,cnt2-cnt3))==mp.end())            mp[make_pair(cnt1-cnt2,cnt2-cnt3)]=i;        else             ans=max(ans,i-mp[make_pair(cnt1-cnt2,cnt2-cnt3)]);    }    cout << ans;}
0 0