打cf的时候遇到的问题,clairs告诉我这是POI2012 的原题。。原谅我菜没写过。。于是拐过来写这道题并且学了下string hash。
 
字符串hash基于Rabin-Karp算法,并且对于各种长度子串的匹配是常数的。具体做法看代码就明白了。然后如果单hash没发过。那就试试双hash把。如果还不行那就三hash以此类推。。一般到双hash就基本不会出错。你的hash的mod值要尽量分开和是素数就对了。
这种方法实在是神,当数据过大时才会可能出错2333很适合竞赛。
附加一个类似双hash的做法,zy大神的做法。就是一个hash还是正常的hash,另一个hash则被替代成了这两段子串的ascii总和的比较。这个做法也是很不错的。
推荐07年杨弋的论文《Hash在信息学竞赛中的一类应用》,对hash应用讲解很不错。

2803: [Poi2012]Prefixuffix

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 434  Solved: 175
[Submit][Status][Discuss]

Description

对于两个串S1、S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同。例如串ababba和串abbaab是循环相同的。
给出一个长度为n的串S,求满足下面条件的最大的L:
1. L<=n/2
2. S的L前缀和S的L后缀是循环相同的。

Input

第一行一个正整数n (n<=1,000,000)。第二行n个小写英文字母,表示串S。

Output

一个整数,表示最大的L。

Sample Input

15
ababbabababbaab

Sample Output

6

HINT

 

Source

 

 
代码其实大同小异。。hash代码长得都差不多,我双hash过得。
首先如果是循环同构,匹配的两串中一串相当于另一个串的左端部分的串被取出放到了右端。例如abcdefg和cdefgab。那么就题目给出的字符串,我们查找同构的前缀和后缀,同构的字符串就可以分为两部分,一部分就是前面说的左端换到右端的串,这两串是相同的,另一部分就是不动的串。因此我们枚举所有可能被换到右端的长度i,先检查转换串[1,i]和[i,n-i+1]是否匹配,然后计算[i+1,n-i]前后缀最长匹配长度f[i+1]。这样算出来的f[i+1]+i最大的即为答案。
而我们可以发现f[i]≤f[i+1]+2,因为[i,n-i+1]比[i+1,n-i]首尾各多了两个字符,对应最长匹配的串首和尾。自己纸上写写就知道了。
因此我们i从n/2枚举到1,得出最长的那个即为答案。
注意L≤n/2,所以你这个同构串是不能重叠的。
 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define LL long long
//usually mod num is 1004535809 99824435 1000000007
#define pnum 233
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e6+;
int f[N],power[N][],hash[N][],mod[]={,};
inline int gethash(int l,int r,int x)
{
return (hash[r][x]-(LL)hash[l-][x]*power[r-l+][x]%mod[x]+mod[x])%mod[x];
}
inline bool check(int x,int y,int len)
{
return gethash(x,x+len-,)==gethash(y,y+len-,) && gethash(x,x+len-,)==gethash(y,y+len-,);
}
int n,ans;
char s[N];
int main()
{
scanf("%d",&n);
scanf("%s",s);
power[][]=power[][]=;
hash[][]=hash[][]=;
for(int i=;i<=n;i++)
for(int j=;j<;j++)
{
power[i][j]=(LL)power[i-][j]*pnum%mod[j];
hash[i][j]=((LL)hash[i-][j]*pnum+(s[i-]-'a'))%mod[j];
}
f[n/+]=;
ans=;
for(int i=n/;i>=;i--)
{
f[i]=min(f[i+]+,n/-i+);
while(f[i] && !check(i,n-i-f[i]+,f[i])) f[i]--;
if(check(,n-i+,i-))
ans=max(f[i]+i-,ans);
}
printf("%d\n",ans);
return ;
}

bzoj 2803 [Poi2012]Prefixuffix 兼字符串hash入门的更多相关文章

  1. bzoj 2803 [POI2012]prefixuffix hsh+性质

    题目大意 bzoj 2803 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串abbaab是循环相同的. 给出一个长度为n的串S,求满 ...

  2. BZOJ 2795: [Poi2012]A Horrible Poem( hash )

    ...字符串hash. 假如长度x是一个循环节, 那么对于任意n(x | n)也是一个循环节. 设当前询问区间[l, r]长度为len = ∏piai, 最终答案ans = ∏piai' ,我们只需枚 ...

  3. 字符串hash入门

    简单介绍一下字符串hash 相信大家对于hash都不陌生 翻译过来就是搞砸,乱搞的意思嘛 hash算法广泛应用于计算机的各类领域,像什么md5,文件效验,磁力链接 等等都会用到hash算法 在信息学奥 ...

  4. bzoj 2795 [Poi2012]A Horrible Poem hash+数论

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 640  Solved: 322[Subm ...

  5. bzoj 2795 [Poi2012]A Horrible Poem hash+线性筛

    题目大意 bzoj 2795 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节. 如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. n<=500 ...

  6. HDU 1880 字符串hash 入门题

    Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔 ...

  7. [BZOJ2803][Poi2012]Prefixuffix

    2803: [Poi2012]Prefixuffix Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 219  Solved: 95[Submit][St ...

  8. [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)

    [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...

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

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

随机推荐

  1. 【BZOJ】1718: [Usaco2006 Jan] Redundant Paths 分离的路径

    [题意]给定无向连通图,要求添加最少的边使全图变成边双连通分量. [算法]Tarjan缩点 [题解]首先边双缩点,得到一棵树(无向无环图). 入度为1的点就是叶子,两个LCA为根的叶子间合并最高效,直 ...

  2. 【洛谷 P2762】 太空飞行计划问题(最大权闭合图)

    题目链接 最大权闭合图模型,参考 具体做法是从源点向每个实验连一条流量为这个实验的报酬的边,从每个实验向这个实验需要的所有器材各连一条流量为\(INF\)的边,再从每个器材向汇点连一条流量为这个器材的 ...

  3. ASP.NET 简单鼠标右键效果contextmenutrip

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  4. sublime3 快捷键大全

    Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所有打开文件Ctrl+Shift+V:粘贴并格 ...

  5. js_layer弹窗的使用和总结

    2018-04-10 一张呈现给用户的网页,会有很多种交互,比如连不上网络,用户点击按钮时向后台请求数据不成功等等.像这些情况,用户是看不见的, 要给用户更好的体验,在特定的时间,给客户反馈内容.实时 ...

  6. js作用域与上下文

    作用域:与调用函数,访问变量的能力有关 作用域分为:局部和全局(在局部作用域里可以访问到全局作用域的变量,但在局部作用域外面就访问不到局部作用里面所设定的变量) 上下文:与this关键字有关 是调用当 ...

  7. Python-字符串处理 str.format()

    Python中内置的%操作符可用于格式化字符串操作,控制字符串的呈现格式.Python中还有其他的格式化字符串的方式,但%操作符的使用是最方便的. 另外python还有一个更强大的字符串处理函数 st ...

  8. Linux-进程间通信(三): 共享内存

    1. 共享内存: 共享内存方式可以在多个进程直接共享数据,因为其直接使用内存,不要多余的拷贝,是速度最快的IPC方式: 共享内存有两种实现方式,使用mmap和shm方式,如下图: (1) mmap方式 ...

  9. python实战===itchat

    import itchat itchat.login() friends=itchat.get_friends(update=True)[0:] male=female=other=0 for i i ...

  10. Linux内核基础--事件通知链(notifier chain)good【转】

    转自:http://www.cnblogs.com/pengdonglin137/p/4075148.html 阅读目录(Content) 1.1. 概述 1.2.数据结构 1.3.  运行机理 1. ...