【题解】 bzoj3555: [Ctsc2014]企鹅QQ (字符串Hash)

题面戳我

Solution

  • 我们分析题意,他要求的是两个字符串只有一个字符不同,然后我们再看长度\(L \leq 200\),显然我们就可以把每一位删除后\(Hash\),然后判断相同个数即可
  • 我一开始脑子抽了,把所有的删掉的一个字符的剩余的串\(Hash\)放在一起然后计算答案,那样\(Hash\)值相同,串不同的可能性大大增加,所以我们就可以每一位每一位分开考虑
  • 具体看代码即可
  • 说是最水的CTSC的题目,我还写了一晚上qwq,我真菜啊qwq

Code

//It is coded by ning_mew on 7.24
#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int maxn=30007;

int n,L,S;
char ch[210];
unsigned LL box[maxn],cnt=0;
unsigned LL f[maxn][205],g[maxn][205],Pow[3][maxn],ans=0;

LL gi(char c){
	if(c>='a'&&c<='z')return (LL)(c-'a'+1);
	if(c>='A'&&c<='Z')return (LL)(c-'A'+1+26);
	if(c>='0'&&c<='9')return (LL)(c-'0'+1+52);
	if(c=='@')return 63;return 64;
}
bool cmp(const LL &x,const LL &y){return x<y;}
int main(){
	scanf("%d%d%d",&n,&L,&S);
	for(int i=1;i<=n;i++){
		scanf("%s",ch+1);
		unsigned LL boxx=0;
		for(int j=1;j<=L;j++){
			boxx=boxx*233+gi(ch[j]);
			f[i][j]=boxx;
		}
		boxx=0;
		for(int j=L;j>=1;j--){
			boxx=boxx*213+gi(ch[j]);
			g[i][j]=boxx;
		}
	}
	int last=0;
	for(int i=1;i<=L;i++){
		cnt=0;last=0;
		for(int j=1;j<=n;j++){box[++cnt]=f[j][i-1]*277+g[j][i+1]*217;}
		sort(box+1,box+cnt+1,cmp);
		for(int j=1;j<=cnt;j++){
			if(box[j]!=box[j+1]){ans+=1ll*(j-last)*(j-last-1)/2;last=j;}
		}
	}
	printf("%lld\n",ans); return 0;	
}

博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/Ning-Mew/,否则你会场场比赛暴0!!!

posted @ 2018-08-25 19:31  Ning_Mew  阅读(279)  评论(0编辑  收藏  举报