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

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

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\n",ans);
return 0;
}

【字符串哈希】bzoj3555 [Ctsc2014]企鹅QQ的更多相关文章

  1. bzoj3555: [Ctsc2014]企鹅QQ

    将字符串hash.不难写.然而1.注意用longlong2.数组大小注意...3.似乎别人都用的unsigned long long ?. #include<cstdio> #includ ...

  2. 字符串Hash || BZOJ 3555: [Ctsc2014]企鹅QQ || P4503 [CTSC2014]企鹅QQ

    题面:[CTSC2014]企鹅QQ 题解:无 代码: #include<iostream> #include<cstring> #include<cstdio> # ...

  3. bzoj3555 [Ctsc2014]企鹅QQ——字符串哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3555 很久以前就讲过哈希,但一直没写过题,所以这是哈希第一题! 哈希就是把一个字符串映射成一 ...

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

    题面戳我 Solution 我们分析题意,他要求的是两个字符串只有一个字符不同,然后我们再看长度\(L \leq 200\),显然我们就可以把每一位删除后\(Hash\),然后判断相同个数即可 我一开 ...

  5. BZOJ3555 [Ctsc2014]企鹅QQ[暴力+字符串hash]

    菜到自闭,一道省选小水题都能给我做繁. 要求有一位不同,则对每个串每一位暴力枚举把这一位删掉,放一个分隔符,算一下hash,插表,相似的都应该会被插入同一个桶.最后把hash统计一下即可.复杂度$O( ...

  6. BZOJ3555 [Ctsc2014]企鹅QQ 题解

    题目大意: 有一些字符串,求其中两个等长且恰好只有一位不同的字符串的对数. 思路: Hash大法好!正着倒着各来一遍(底数不同),之后枚举不同的那一位,前后两段拼起来之后为了有区分前面一部分再乘一个数 ...

  7. BZOJ3555 [Ctsc2014]企鹅QQ 【hash】

    题目 PenguinQQ是中国最大.最具影响力的SNS(Social Networking Services)网站,以实名制为基础,为用户提供日志.群.即时通讯.相册.集市等丰富强大的互联网功能体验, ...

  8. bzoj3555: [Ctsc2014]企鹅QQ (Hash)

    枚举每个分段的点,每次O(n)更新左边和右边的hash值 然后用双指针O(n)计算答案 #include<stdio.h> #include<string.h> #includ ...

  9. [BZOJ3555] [Ctsc2014]企鹅QQ(Hash)

    传送门 可以枚举被删除的位置,然后用hash表判重,然而网上好多题解都是用 sort 判重的. 不知道为什么,int 总是过不了,换成 long long 或者是 unsigned long long ...

随机推荐

  1. [SDOI2016] 排列计数 (组合数学)

    [SDOI2016]排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰 ...

  2. CentOS 64位上编译 Hadoop2.6.0

    由于hadoop-2.6.0.tar.gz安装包是在32位机器上编译的,64位的机器加载本地库.so文件时会出错,比如: java.lang.UnsatisfiedLinkError: org.apa ...

  3. 转:JVM Server与Client运行模式

    转自:http://blog.csdn.net/zhuyijian135757/article/details/38391785 JVM Server模式与client模式启动,最主要的差别在于:-S ...

  4. python并发进程

    1 引言 2 创建进程 2.1 通过定义函数的方式创建进程 2.2 通过定义类的方式创建进程 3 Process中常用属性和方法 3.1 守护进程:daemon 3.2 进程终结于存活检查:termi ...

  5. codevs1063 合并果子 优先队列(小根堆)

    题目传送门 这道题很容易想到优先把两堆重量最小的合并比较优 然后乱搞一下就可以啦 #include<cstdio> #include<cstring> #include< ...

  6. 【洛谷 P1651】 塔 (差值DP)

    题目链接 题意:\(n\)个木块放到两个塔里,每个木块可放可不放,使得两塔高度相同且高度最大,求最大高度. 这个差值\(DP\)的思维难度还是很大的,没想出来,我就打了一个\(dfs\)骗了好像\(2 ...

  7. linux基础的基础命令操作

    一.开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 操作:su - root 二.使用快捷键切换到虚拟终端2,使用普通用户身份登录,查看系统提示符 操作:ctrl ...

  8. HDU3910(数学期望题,题目难懂)

    Liang Guo Sha Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  9. 自动化测试===【转】Robot Framework作者建议如何选择自动化测试框架

    原文:http://www.infoq.com/cn/news/2012/06/robot-author-suggest-autotest 软件自动化测试,作为手工测试的替代,越来越受到关注.Pekk ...

  10. 一次Ubuntu下的排雷记录

    起因 某天,发现一台服务器上出现了一个大量占用cpu资源的进程.尝试手动杀掉,但很快就会自动重新创建新的进程. 追查 用命令lsof -p 10316 查看其文件路径: 该进程文件夹/proc/103 ...