zoukankan      html  css  js  c++  java
  • [bzoj4236]JOIOJI

    来自FallDream的博客,未经允许,请勿转载,谢谢。

    JOIOJI桑是JOI君的叔叔。“JOIOJI”这个名字是由“J、O、I”三个字母各两个构成的。
    最近,JOIOJI桑有了一个孩子。JOIOJI桑想让自己孩子的名字和自己一样由“J、O、I”三个字母构成,并且想让“J、O、I”三个字母的出现次数恰好相同。
    JOIOJI桑家有一份祖传的卷轴,上面写着一首长诗,长度为N,由“J、O、I”三个字母组成。JOIOJIさん想用诗中最长的满足要求的连续子串作为孩子的名字。
    现在JOIOJI桑将这首长诗交给了你,请你求出诗中最长的、包含同样数目的“J、O、I”三个字母的连续子串。
    n<=2*10^5
     
    就是个哈希qaq
    假设三种字母的数量分别是a,b,c
    那么数量相同的字串,a-b b-c c-a肯定都相同,拿出来哈希一下就好了。
    #include<iostream>
    #include<cstdio>
    #include<map>
    #define MN 200000
    #define magic 73
    #define magic2 233333333
    #define ll long long
    using namespace std;
    int X;char ch;
    inline int read()
    {
        X = 0 , ch = getchar();
        while(ch < '0' || ch > '9') ch = getchar();
        while(ch >= '0' && ch <= '9'){X = X * 10 + ch - '0';ch = getchar();}
        return X;
    }
    
    int a,b,c,n,ans=0;
    char st[MN+5];
    map<ll,int> mp;
    
    void ins(int num)
    {
        ll hash=(1LL*(b-a+magic)*magic+(b-c+magic))*magic2+c-a;
        int t=mp[hash];
        if(t) ans=max(ans,num-t+1);
        else mp[hash]=num+1;
    }
    
    int main()
    {
        n=read();scanf("%s",st+1);ins(0);
        for(int i=1;i<=n;i++)
        {
            st[i]=='J'?a++:(st[i]=='O'?b++:c++);
            ins(i);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    文艺青年会看这本《迷局》么?
    看文艺青年怎么玩微信客户端
    Sublime Text有哪些使用技巧(转)
    C++ 关键字 explicit, export, mutable
    move语义和右值引用
    C++11 std::function用法
    function adapter(函数适配器)和迭代器适配器
    for_each()的返回值
    C++11的一些新特性
    setw和setfill控制输出间隔
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj4236.html
Copyright © 2011-2022 走看看