zoukankan      html  css  js  c++  java
  • hdu-4080 Stammering Aliens 字符串hash 模板题

    http://acm.hdu.edu.cn/showproblem.php?pid=4080

    求出现次数大于等于n的最长串。

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include <string>
    #include <map>
    #define LL long long
    using namespace std;
    const LL p=1e9+7;
    const LL mod=1e9+9;//23333 951413 11111111111111111111111
    const LL N=100005;
    string s;
    LL n,st;
    LL has[N];//计算前缀has
    LL xp[N];//计算p的次方值,用于还原区间hash
    LL fastMi(LL a,LL b){
        LL k,mut=1;
        if(b==0) return 1;
        k=a*a;
        if(b%2!=0) mut*=a;
        mut*=fastMi(k,b/2);
        return mut;
    }
    int idx(char x)
    {
        return x-'a'+1;
    }
    void ini_has()
    {
        xp[0]=1;
        for(int i=1;i<N;i++)
            xp[i]=xp[i-1]*p,xp[i]%=mod;
    }
    void m_has(string &s)
    {
        has[0]=0;
        for(int i=1;i<=s.length();i++)
            has[i]=(has[i-1]*p+idx(s[i-1]))%mod;
    }
    LL g_has(int l,int r)//[l+1,r]
    {
        return ((has[r]-has[l]*xp[r-l])%mod+mod)%mod;
    }
    struct node
    {
        int c;
        int s;
        node(int cc,int ss)
        {
            c=cc;
            s=ss;
        }
        node(){
        }
    };
    bool ok(int len)
    {
        //cout<<len<<endl;
        map<int,node> mp;
        for(int i=0;i+len<=s.length();i++)
        {
            LL h=g_has(i,i+len);
            if(mp.find(h)==mp.end())
                mp[h]=node(1,i);
            else
            {
                mp[h].c++;
                mp[h].s=i;
            }
        }
        bool f=false;
        st=-1;
        for(map<int,node>::iterator it=mp.begin();it!=mp.end();it++)
        {
            if(it->second.c>=n)
            {
                f=true;
                st=max(st,(LL)it->second.s);
            }
        }
        return f;
    }
    int bins(int l,int r)
    {
        while(r-l>=3)
        {
            int mid=(l+r)/2;
            if(ok(mid))l=mid;
            else r=mid-1;
        }
        for(int i=r;i>=l;i--)
            if(ok(i))return i;
        return 0;
    }
    int main()
    {
        cin.sync_with_stdio(false);
        ini_has();
        while(cin>>n)
        {
            if(!n)break;
            cin>>s;
            has[0]=0;
            m_has(s);
            int ans=bins(1,s.length());
            if(ans)
            {
                cout<<ans<<' '<<st<<endl;
            }else{ cout<<"none"<<endl;}
        }
        return 0;
    }
  • 相关阅读:
    冒泡排序
    数组去重
    DOM 操作入门(二)
    DOM 操作入门(一)----- 在指定位置动态插入节点
    事件流的捕获和冒泡 ---- 事件对象
    call, apply, bind -----【改变this指向的三大利器】
    闭包和垃圾回收机制
    回调函数 -----【全球化下的产业分工】
    处理Excel表格里面的数据
    Web后台获取服务器相关信息
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/7739142.html
Copyright © 2011-2022 走看看