【POJ】【P2774】【Long Long Message】【题解】【hash】

传送门:http://poj.org/problem?id=2774

sth神犇说hash可以干任何字符串的事情……于是我就拿hash乱搞了……原来用hash+二分套hash,然后WAWAWAWA,于是改成hash+二分套二分,A了复杂度O(nlog^2n)

Code:

#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
typedef unsigned long long UL;
int len1,len2,mid;
UL hash1[maxn],hash2[maxn],hash_l[maxn],base=2333333;
UL hash[maxn];
char s1[maxn],s2[maxn];
void hash_init(){
	UL val=0;hash_l[0]=1;
	for(int i=1;i<=len1;i++){
		val=val*base+s1[i]-'0';
		hash1[i]=val;
	}val=0;
	for(int i=1;i<=len2;i++){
		val=val*base+s2[i]-'0';
		hash2[i]=val;
	}int maxx=max(len1,len2);
	for(int i=1;i<=maxx;i++)
		hash_l[i]=hash_l[i-1]*base;
}
int main(){
	scanf("%s%s",s1+1,s2+1);
	len1=strlen(s1+1);len2=strlen(s2+1);
	hash_init();
	int l=0,r=min(len1,len2)+1;
	while(l<r){
		mid=(l+r)>>1;
		hash[0]=0;
		for(int i=mid;i<=len1;i++)
		hash[++hash[0]]=(hash1[i]-hash1[i-mid]*hash_l[mid]);
		sort(hash+1,hash+1+hash[0]);
		bool ok=0;
		for(int i=mid;i<=len2;i++){
			UL x=(hash2[i]-hash2[i-mid]*hash_l[mid]);
			if(*lower_bound(hash+1,hash+1+hash[0],x)==x){
				ok=1;break;
			}
		}
		
		if(ok)
			l=mid+1;
		else
			r=mid;
	}printf("%d\n",l-1);
	return 0;
}


你可能感兴趣的:(poj)