LA 4513 Stammering Aliens(哈希写起来比后缀数组爽多了)

LA  4513

求至少出现m次最长子串。

如果用后缀数组写,要二分长度,对sa[ ] 进行分组,看有没有一个组的元素个数不小于m  。

用哈希写, 同样是二分长度,代码量只有一半。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <hash_set>
using namespace std;
typedef unsigned long long uLL ;
const int maxn = 40050  ;

int pos ;
const uLL p = 9999997 ;
uLL powp[maxn] ;
uLL hash[maxn] ;
char s[maxn] ;


const int HashNum=1<<16;
struct HASH{
	int flag[HashNum];
	uLL has[HashNum];
	void Init(){
        memset(flag , 0 ,sizeof(flag)) ;
	}
	int Hash(uLL k)
	{
	    int p=k%HashNum;
	    while(flag[p] && has[p]!=k)
	        p=(p+1)%HashNum;
	    return p ;
	}
	int Insert(uLL k){
		int p=Hash(k);
		has[p]=k;
		return ++flag[p];
	}
}hs ;


bool check(int l , int n , int m){
    hs.Init();
    bool ok = false ;
    for(int i=1; i+l-1<=n; i++) {
        uLL tmp = hash[i+l-1] - hash[i-1] * powp[l];
        if( hs.Insert(tmp) >=m )
        {pos = i ; ok = true ; }
    }
    return ok ;
}

int main()
{
    powp[0] = 1 ;
    for(int i=1; i<maxn; i++) powp[i] = powp[i-1] * p ;
    int m  ;
    while(scanf("%d" ,&m)==1 && m){
        scanf("%s" ,s+1) ;
        int n = strlen(s+1) ;
        hash[0] = hash[n+1] = 0 ;
        for(int i=1; i<=n;i++) hash[i] = hash[i-1]*p + s[i] ;
        int L = 0 , R = n ;
        while(L<R) {
            int mid = L + (R-L+1)/2 ;
            if(check(mid , n ,m)) L = mid ;
            else R = mid - 1 ;
        }
        if(!L) puts("none") ;
        else printf("%d %d\n" , L , pos-1) ;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值