萌新刚学 OI,求助哈希 30pts 惨烈 TLE
查看原帖
萌新刚学 OI,求助哈希 30pts 惨烈 TLE
360511
UperFicial楼主2021/8/30 20:11
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN(60);
const int LEN(1e5);
const int MAXM(1e5+10);
typedef unsigned long long ll;
int n,len[MAXN];
char s[MAXN][MAXM];
int ans[MAXN][MAXN];
struct HASH
{
	ll Hash[MAXM];
	ll fac[MAXM],Base;
	inline void init__(ll B)
	{
		fac[0]=1ll,Base=B;
		for(register int i=1;i<=LEN;i++)
			fac[i]=fac[i-1]*B;
		return;
	}
	inline void make_hash(int k)
	{
		for(register int i=1;i<=len[k];i++)
			Hash[i]=Hash[i-1]*Base+s[k][i];
		return;
	}
	inline ll gethash(int l,int r){return Hash[r]-Hash[l-1]*fac[r-l+1];}
};
HASH h1[2],h2[2];
inline bool check(int L,int x,int y)
{
	h1[0].make_hash(x);
	h2[0].make_hash(y);
	h1[1].make_hash(x);
	h2[1].make_hash(y);
	for(register int i=1;i+L-1<=len[x];i++)
	{
		int lf=i,rf=i+L-1;
		ll v1=h1[0].gethash(lf,rf);
		ll v2=h1[1].gethash(lf,rf);
		for(register int j=1;j+L-1<=len[y];j++)
		{
			lf=j,rf=j+L-1;
			ll vv1=h2[0].gethash(lf,rf);
			ll vv2=h2[1].gethash(lf,rf);
			if(v1==vv1&&v2==vv2) return true;
		}
	}
	return false;
}
inline int solve(int x,int y)
{
	int l=1,r=len[x],tmp(0);
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(check(mid,x,y)) l=mid+1,tmp=mid;
		else r=mid-1;
	}
	return tmp;
}
int main()
{
	scanf("%d",&n);
	h1[0].init__(23);
	h1[1].init__(131);
	h2[0].init__(23);
	h2[1].init__(131);
	for(register int i=1;i<=n;i++)
	{
		scanf("%s",s[i]+1);
		len[i]=strlen(s[i]+1);
	}
	for(register int i=1;i<=n;i++)
		for(register int j=i+1;j<=n;j++)
			ans[i][j]=ans[j][i]=solve(i,j);
	for(register int i=1;i<=n;i++)
	{
		for(register int j=1;j<=n;j++) if(j!=i)
			printf("%d ",ans[i][j]);
		puts("");
	}
	return 0;
}
2021/8/30 20:11
加载中...