[BZOJ3555][CTSC2014]企鹅QQ
题意
给你\(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;
}