[BZOJ3555][CTSC2014]企鹅QQ

bzoj

题意

给你\(n\)个长为\(L\)且互不相同的字符串,定义两个串相似当且仅当两个串只有一个位置不同。求相似的串的对数。
\(n\le30000,L\le200\)

sol

枚举一下不同的那个位置,这样就要求前后都必须完全相同。
对每个串的前缀后缀哈希即可。
(单哈希居然过了)

code

#include<cstdio>
#include<algorithm>
#define ull unsigned long long
using namespace std;
const int N = 3e4+5;
const int L = 205;
int n,l,ans;
ull pre[N][L],suf[N][L],o[N];
char s[L];
int main()
{
	scanf("%d%d%d",&n,&l,&ans);ans=0;
	for (int i=1;i<=n;++i)
	{
		scanf("%s",s+1);
		for (int j=1;j<=l;++j) pre[i][j]=pre[i][j-1]*19260817+s[j];
		for (int j=l;j>=1;--j) suf[i][j]=suf[i][j+1]*23333333+s[j];
	}
	for (int i=1;i<=l;++i)
	{
		for (int j=1;j<=n;++j) o[j]=pre[j][i-1]*666+suf[j][i+1]*667;
		sort(o+1,o+n+1);
		for (int j=2,sum=1;j<=n;++j)
			if (o[j]==o[j-1]) ans+=sum++;
			else sum=1;
	}
	printf("%d\n",ans);return 0;
}
posted @ 2018-04-13 15:34  租酥雨  阅读(193)  评论(0编辑  收藏  举报