Similar substrings Hash + two points)

Insert picture description here
Insert picture description here
Analysis: The
essence of the problem let us solve is to select k disjoint substrings in the main string. What is the longest length of this substring. In fact, the answer is monotonic and the solution is dichotomous.
We first preprocess the string hash, and then divide the answer into two
parts. Judgment part:
use two hash tables to record the position of the substring of length len and the number of substrings of length len, and record them as V and T to
judge the length each time. Is a substring of len, judge whether the position with the previous record is legal, and update V and T if it is legal

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10000;
typedef unsigned long long ull;
ull P=131;
ull h[N],p[N];
char s[N];
int n,k;
unordered_map<ull,int> v,t; 
ull get(int l,int r)
{
	return h[r]-h[l]*p[r-l];
}
bool check(int len)
{
	v.clear();t.clear();
	for(int i=len;i<=n;i++)
	{
		ull m=get(i-len,i);
		if(!v[m]) v[m]=i,t[m]++;
		else if(v[m]<=i-len) v[m]=i,t[m]++;
		if(t[m]>=k) return 1;
		
	}
	return 0;
}
int main()
{
	cin>>n>>k;
	cin>>(s+1);
	p[0]=1;
	for(int i=1;i<=n;i++)
	{
		p[i]=p[i-1]*P;
		h[i]=h[i-1]*P+(s[i]-'a'+1);
	}
	int l=0,r=n/k;
	while(l<r)
	{
		int mid=l+r+1>>1;
		if(check(mid)) l=mid;
		else r=mid-1;
	 } 
	 cout<<l<<endl;
}

Published 572 original articles · praised 14 · 10,000+ views

Guess you like

Origin blog.csdn.net/qq_43690454/article/details/105453815