zoj3395后缀树组-2

 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3971

题意:求一个数组中重复出现至少m次的最长字串。。。

 

分析:二分答案进行判断即可。。对每个判断的长度,只需要看连续在这段里面的height>=mid的个数是不是>=m-1即可。。

ps:本题刷到rank1了,呵呵。。

 

关键代码:240ms

void print(int mid)
{
	int i, j, mx, right=-1;
	for(i=1; i<=len; )
	{
		while(i<=len && height[i]<mid)
			i++;
		j=i;
		mx = 0;
		if(sa[i-1]>mx)
			mx = sa[i-1];
		while(j<=len && height[j]>=mid)
		{
			if(sa[j]>mx)
				mx = sa[j];
			j++;
		}
		if(j-i>=m-1)
		{
			if(mx>right)
				right = mx;
		}
		i = j;
	}
	printf("%d %d\n", mid, right);
}

int main()
{
	int i, l, r, mid, ans;
	while(scanf("%d", &m)!=EOF)
	{
		if(m==0)
			break;
		//scanf("%s", s);
		gets(s);
		gets(s);
		len = strlen(s);
		if(m==1)
		{
			printf("%d 0\n", len);
			continue;
		}
		for(i=0; i<len; i++)
			a[i] = s[i]-'a'+1;
		a[len] = 0;
		dc3(a, sa, len+1, 28);
		calheight(a, sa, len);
		l=0, r=len-1;
		while(l<=r)
		{
			mid = (l+r)>>1;
			if(check(mid))
				l = mid+1;
			else
				r = mid-1;
		}
		ans = r;
		if(ans==0)
			printf("none\n");
		else
			print(ans);
	}

	return 0;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值