zoukankan      html  css  js  c++  java
  • 【字符串哈希】bzoj3555 [Ctsc2014]企鹅QQ

    枚举每个位置,给每个串的前半部分一个哈希值,后半部分一个哈希值,若是它们均相等,则视为这两个串相似。

    每次转移之后,排序一下就行了。

    O(L*n*log(n))。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef unsigned long long ull;
    struct HASH{ull l,r;}hss[30001],tmp[30001];
    bool operator < (const HASH &a,const HASH &b){return a.l!=b.l ? a.l<b.l : a.r<b.r;}
    bool operator != (const HASH &a,const HASH &b){return (a.l!=b.l||a.r!=b.r);}
    ull seed,seeds[201];
    int ord[301],n,m,ans;
    char s[30001][201];
    void init()
    {
    	if(seed==2) ord['0']=1,ord['1']=2;
    	else
    	  {
    	  	int en=0;
    	  	for(char c='A';c<='Z';++c) ord[c]=++en;
    	  	for(char c='a';c<='z';++c) ord[c]=++en;
    	  	for(char c='0';c<='9';++c) ord[c]=++en;
    	  	ord['_']=++en; ord['@']=++en;
    	  }
    	++seed; seeds[0]=1;
    	for(int i=1;i<=m;++i)
    	  seeds[i]=seeds[i-1]*seed;
    }
    int main()
    {
    	scanf("%d%d",&n,&m); cin>>seed;
    	init();
    	for(int i=1;i<=n;++i)
    	  {
    	  	scanf("%s",s[i]);
    	  	for(int j=1;j<m;++j)
    	  	  hss[i].r=hss[i].r*seed+(ull)ord[s[i][j]];
    	  }
    	memcpy(tmp,hss,(n+1)*sizeof(HASH));
    	for(int i=1;i<=m;++i)
    	  {
    	  	int head;
    	  	sort(hss+1,hss+n+1);
    	  	for(int j=1;j<=n;++j)
    	  	  {
    	  	  	tmp[j].l=tmp[j].l*seed+(ull)ord[s[j][i-1]];
    	  	  	tmp[j].r-=seeds[m-1-i]*(ull)ord[s[j][i]];
    	  	  	if(j==1 || hss[j]!=hss[j-1]) head=j;
    	  	  	if(j==n || hss[j]!=hss[j+1]) ans+=(((j-head+1)*(j-head))>>1);
    	  	  }
    	  	memcpy(hss,tmp,(n+1)*sizeof(HASH));
    	  }
    	printf("%d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    ~随笔A016~分布式技术发展
    BoF图像检索
    立体匹配-----NCC视差匹配
    对极几何与基础矩阵
    相机标定
    图像的拼接----RANSAC算法
    SIFT特征提取与检索
    Harris角点检测
    Python---图像基础处理
    PSO算法
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4189955.html
Copyright © 2011-2022 走看看