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;
}

 

posted @ 2017-10-26 20:19  Luke_Ye  阅读(456)  评论(0编辑  收藏  举报