首页 > 代码库 > [字符串hash] hdu 4821 String

[字符串hash] hdu 4821 String

题意:

给你M,L,再给一个串str

任意截取M*L长度的连续子串

再把这个子串分成M份长度为L的连续串

使得这M份互不相同

问有几种截取方法

思路:

考虑到子串是否相等,就运用字符串hash

用到map判重和割补的办法优化

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"map"
#include"vector"
#include"string"
#define inf 0x7fffffff
#include"iostream"
using namespace std;
#define ll unsigned __int64
const ll maxn=100100;
ll hash[maxn],base[maxn],cnt[maxn*10];
char s[maxn];
void init(ll len)
{
    ll seed=131;
    hash[0]=0;
    base[0]=1;
    for(ll i=1; i<=len; i++)
    {
        hash[i]=hash[i-1]*seed+s[i];
        base[i]=base[i-1]*seed;
    }
}
ll gethash(ll L,ll R)
{
    return hash[R]-hash[L-1]*base[R-L+1];
}
int main()
{
    ll m,l;
    while(scanf("%I64u%I64u",&m,&l)!=-1)
    {
        ll ans=0,lit=m*l;
        scanf("%s",s+1);
        ll len=strlen(s+1);
        init(len);
        for(ll i=1; i<=l; i++)
        {
            map<ll,ll>mark;
            ll sum=1,ssb=0;
            for(ll j=i; j<=i+lit-1; j+=l)     //以首开头的 先取第一个M份
            {
                ll tep=gethash(j,j+l-1);
                if(mark[tep]==0)
                {
                    mark[tep]=sum++;
                    ssb++;
                    cnt[mark[tep]]=0;
                }
                cnt[mark[tep]]++;
            }
            if(ssb==m) ans++;
            for(ll j=i+lit; j+l-1<=len; j+=l)
            {
                ll tep=gethash(j-lit,j-lit+l-1);
                cnt[mark[tep]]--;                //删掉第一份中长度L的串
                if(cnt[mark[tep]]==0)
                {
                    ssb--;
                    mark[tep]=0;
                }
                tep=gethash(j,j+l-1);            //加上后面长度为L的串
                if(mark[tep]==0)
                {
                    mark[tep]=sum++;
                    ssb++;
                    cnt[mark[tep]]=0;
                }
                cnt[mark[tep]]++;
                if(ssb==m) ans++;
            }
        }
        printf("%I64u\n",ans);
    }
    return 0;
}



[字符串hash] hdu 4821 String