【字符串哈希】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\n",ans);
return 0;
}
【字符串哈希】bzoj3555 [Ctsc2014]企鹅QQ的更多相关文章
- bzoj3555: [Ctsc2014]企鹅QQ
将字符串hash.不难写.然而1.注意用longlong2.数组大小注意...3.似乎别人都用的unsigned long long ?. #include<cstdio> #includ ...
- 字符串Hash || BZOJ 3555: [Ctsc2014]企鹅QQ || P4503 [CTSC2014]企鹅QQ
题面:[CTSC2014]企鹅QQ 题解:无 代码: #include<iostream> #include<cstring> #include<cstdio> # ...
- bzoj3555 [Ctsc2014]企鹅QQ——字符串哈希
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3555 很久以前就讲过哈希,但一直没写过题,所以这是哈希第一题! 哈希就是把一个字符串映射成一 ...
- 【题解】 bzoj3555: [Ctsc2014]企鹅QQ (字符串Hash)
题面戳我 Solution 我们分析题意,他要求的是两个字符串只有一个字符不同,然后我们再看长度\(L \leq 200\),显然我们就可以把每一位删除后\(Hash\),然后判断相同个数即可 我一开 ...
- BZOJ3555 [Ctsc2014]企鹅QQ[暴力+字符串hash]
菜到自闭,一道省选小水题都能给我做繁. 要求有一位不同,则对每个串每一位暴力枚举把这一位删掉,放一个分隔符,算一下hash,插表,相似的都应该会被插入同一个桶.最后把hash统计一下即可.复杂度$O( ...
- BZOJ3555 [Ctsc2014]企鹅QQ 题解
题目大意: 有一些字符串,求其中两个等长且恰好只有一位不同的字符串的对数. 思路: Hash大法好!正着倒着各来一遍(底数不同),之后枚举不同的那一位,前后两段拼起来之后为了有区分前面一部分再乘一个数 ...
- BZOJ3555 [Ctsc2014]企鹅QQ 【hash】
题目 PenguinQQ是中国最大.最具影响力的SNS(Social Networking Services)网站,以实名制为基础,为用户提供日志.群.即时通讯.相册.集市等丰富强大的互联网功能体验, ...
- bzoj3555: [Ctsc2014]企鹅QQ (Hash)
枚举每个分段的点,每次O(n)更新左边和右边的hash值 然后用双指针O(n)计算答案 #include<stdio.h> #include<string.h> #includ ...
- [BZOJ3555] [Ctsc2014]企鹅QQ(Hash)
传送门 可以枚举被删除的位置,然后用hash表判重,然而网上好多题解都是用 sort 判重的. 不知道为什么,int 总是过不了,换成 long long 或者是 unsigned long long ...
随机推荐
- PRINT_TABLE 列以行形式显示
在sqlplus,如果列比较多,往往会显示不够清晰,这时如果能把查询语句行转列就明了多了,在网上看到print_table存储过程:里面所设置的日期格式,可根据自己习惯修改 CREATE OR REP ...
- 封装getByClass(JS获取class的方法封装为一个函数)
获取方法一(普通版) 获取单一的class: function getByClass(oParent, sClass) {//两个形参,第一个对象oParent 第二个样式名class var aEl ...
- 在Ubuntu下编译WebKit源码--qt
转载自:http://www.cnblogs.com/panderen/archive/2011/10/18/2216154.html 在朋友的介绍下有幸認识了WebKit这个让人心动的开源浏览器内核 ...
- C# 序列化原因 (转)
1.什么是序列化 序列化是将对象状态转换为可保持或传输的格式的过程,在序列化过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流.与序列化相对 ...
- struts2和jstl有关循环的写法
一:前言 其实觉得自己现在就是个码农啊,对于struts2的标签和jstl的标签我一直都是只会用,但是觉得自己老是会混淆这种概念性的问题.所以我自己在代码里面就试着用了几种方式,实现同一种效果,下面就 ...
- JAVA中List<Long> 转long[]的方法
之前每次都是通过循环去写,感觉代码不够优雅,百度了一下,查到如下的写法,先记下来: List<Long> list = new ArrayList<Long>(); list. ...
- 【poj3415-长度不小于k的公共子串个数】后缀数组+单调栈
这题曾经用sam打过,现在学sa再来做一遍. 基本思路:计算A所有的后缀和B所有后缀之间的最长公共前缀. 分组之后,假设现在是做B的后缀.前面的串能和当前的B后缀产生的公共前缀必定是从前往后单调递增的 ...
- 玩转Metasploit系列(第二集)
在上一节的内容中,大家了解了Metasploit的结构.这一节我们主要介绍的是msfconsole的理论. msfconsole理论 在MSF里面msfconsole可以说是最流行的一个接口程序.很多 ...
- HDU1024(最大M子段和)
Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 关于preempt_enable 和 preempt_disable 【转】
转自:http://blog.chinaunix.net/uid-8478094-id-2031177.html 关于preempt_enable 和 preempt_disable 允许抢占和禁止抢 ...