解题报告 P4503 【[CTSC2014]企鹅QQ】
夏令营讲了,回来巩固一下
1.预处理,算出前i段的哈希值(这里使用的为进制哈希)
2.根据题意,枚举不同位是哪一位,
求所有字符串在去掉这一位后的哈希值,
用排序等方法统计相同的对数。
3.O(lnlog2n)
那么如何求去掉一位的哈希值呢?
设去掉第k位,长度为l
HS=hs[i-1]*base^(l-i)+hs[l]-hs[i]*base^(l-i);
#include<bits/stdc++.h>
#define N 30105
#define ull unsigned long long
using namespace std;
ull hsi[N][250],base=233,mod=2123,hs[N];
ull pw[N];
int n,l,s,ans;
char ss[N][250];
void init(){
pw[0]=1;
for(int i=1;i<=l;i++) pw[i]=pw[i-1]*base;
}//预处理进制
int main()
{
scanf("%d%d%d",&n,&l,&s);
for(int i=1;i<=n;i++) cin>>ss[i];
init();
for(int i=1;i<=n;i++){
for(int j=1;j<=l;j++){
hsi[i][j]=hsi[i][j-1]*base+ss[i][j-1];
}
}//求解哈希值
for(int i=1;i<=l;i++){
for(int j=1;j<=n;j++){
hs[j]=hsi[j][i-1]*pw[l-i]+hsi[j][l]-hsi[j][i]*pw[l-i];
}
sort(hs+1,hs+1+n);
int t=1;
for(int j=1;j<=n;j++){
if(hs[j]!=hs[j-1]) t=1;
else ans+=t,++t;
}//sort+模拟
}cout<<ans;
return 0;
}