题目大意

bzoj 2803

对于两个串S1、S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同。例如串ababba和串abbaab是循环相同的。

给出一个长度为n的串S,求满足下面条件的最大的L:

  1. \(L\le \frac n 2\)
  2. S的L前缀和S的L后缀是循环相同的。

\(n\le 1,000,000\)

分析

题意相当于找一段前缀=后缀(1)

删掉这两段后再找一段前缀=后缀(2)

长度和就是答案了

其中(1)部分随便搞\(O(n)\) \(hsh\)扫过去就好了

为了复习写了发\(kmp\)

(2)部分有一个神性质,可以\(dp\)

记\(f[i]\)表示不跨越\(mid\)的情况下,以\(i\)开头的前缀和以\(n-i+1\)结束的后缀的最大匹配长度

重要性质:$$f[i-1]<=f[i]+2$$

证明:

令\(j=n-i+1\)

设f[i]对应的最长匹配为\([i,A]\) 与 \([B,j]\) (3)

\(f[i-1]\le f[i]+2\)

就是如图



原式相当于\(i-1\)的匹配位置不超过原来匹配位置的下一位

反证一波:

设匹配到第A+K(K>=2)位

则\([i-1~,~A+K]=[B-K~,~j+1]\)

取这两段的第二位到倒数第二位

有\([i,A+K-1]=[B-(K-1)~,~j]\)

(3)矛盾

注意

此题神数据卡hash

于是我开了双hash继续Wa

3hash就过了

所以感觉双hsh姿势应该是

一个自然溢出,一个取模,可能效果更好

kmp姿势

本文kmp姿势错误,切勿学习

solution

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long LL;
const int Q=1000000007;
const int M=1000007;
const ull W=131;
const ull X=1313;
const LL Z=13131; int n;
char s[M];
int f[M];
int nxt[M];
ull hsh1[M],pw1[M];
ull hsh2[M],pw2[M];
LL hsh3[M],pw3[M]; void kmp(){
nxt[1]=0;
int i,k=0;
for(i=1;i<=n;i++){
while(k&&s[k]!=s[i]) k=nxt[k];
nxt[i+1]=++k;
}
} ull gethsh1(int x,int y){
return hsh1[y]-hsh1[x-1]*pw1[y-x+1];
} ull gethsh2(int x,int y){
return hsh2[y]-hsh2[x-1]*pw2[y-x+1];
} LL gethsh3(int x,int y){
return ((hsh3[y]-hsh3[x-1]*pw3[y-x+1]%Q)%Q+Q)%Q;
} int main(){
int i;
scanf("%d",&n);
scanf("%s",s+1);
for(pw1[0]=1,i=1;i<=n;i++) pw1[i]=pw1[i-1]*W;
for(pw2[0]=1,i=1;i<=n;i++) pw2[i]=pw2[i-1]*X;
for(pw3[0]=1,i=1;i<=n;i++) pw3[i]=pw3[i-1]*Z%Q;
for(i=1;i<=n;i++) hsh1[i]=hsh1[i-1]*W+s[i];
for(i=1;i<=n;i++) hsh2[i]=hsh2[i-1]*X+s[i];
for(i=1;i<=n;i++) hsh3[i]=(hsh3[i-1]*Z+s[i])%Q; f[n/2+1]=0;
for(i=n/2;i;i--){
f[i]=f[i+1]+2;
while(f[i]&&i+f[i]-1>n/2) f[i]--;
while(f[i]&&(gethsh1(i,i+f[i]-1)!=gethsh1(n-i+1-f[i]+1,n-i+1)
||gethsh2(i,i+f[i]-1)!=gethsh2(n-i+1-f[i]+1,n-i+1))
||gethsh3(i,i+f[i]-1)!=gethsh3(n-i+1-f[i]+1,n-i+1)) f[i]--;
}
kmp();
int ans=0;
for(i=nxt[n+1];i;i=nxt[i])
if(i<=n/2) ans=max(ans,(i-1)+f[i]); printf("%d\n",ans);
return 0;
}

bzoj 2803 [POI2012]prefixuffix hsh+性质的更多相关文章

  1. bzoj 2803 [Poi2012]Prefixuffix 兼字符串hash入门

    打cf的时候遇到的问题,clairs告诉我这是POI2012 的原题..原谅我菜没写过..于是拐过来写这道题并且学了下string hash.   字符串hash基于Rabin-Karp算法,并且对于 ...

  2. [BZOJ2803][Poi2012]Prefixuffix

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

  3. 【BZOJ2803】[Poi2012]Prefixuffix 结论题

    [BZOJ2803][Poi2012]Prefixuffix Description 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串 ...

  4. 【BZOJ 2803】【POI 2012】Prefixuffix

    http://www.lydsy.com/JudgeOnline/problem.php?id=2803 核心思想是利用单调性. 因为长度为L的前缀和后缀循环同构是AB和BA的形式,我们设\(f(i) ...

  5. bzoj 2799 [Poi2012]Salaries 性质+二分

    题目大意 给出一棵n个结点的有根树,结点用正整数1~n编号. 每个结点有一个1~n的正整数权值,不同结点的权值不相同, 并且一个结点的权值一定比它父结点的权值小(根结点的权值最大,一定是n). 现在有 ...

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

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

  7. Bzoj 2789: [Poi2012]Letters 树状数组,逆序对

    2789: [Poi2012]Letters Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 278  Solved: 185[Submit][Stat ...

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

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

  9. BZOJ 2789: [Poi2012]Letters( BIT )

    直接求逆序对就行了...时间复杂度O(nlogn) ------------------------------------------------------------------------- ...

随机推荐

  1. 《队长说得队》【Alpha】Scrum meeting 5

    项目 内容 这个作业属于哪个课程 >>2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 >>实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 ...

  2. 01_5_删除指定id的单个对象

    01_5_删除指定id的单个对象 1. 配置相应的映射文件内容 <delete id="deleteStudent" parameterClass="int&quo ...

  3. 关于UINavigationController的一些技巧

    未自定义任何东西的导航条效果如下: 1.自定义了 leftBarButtonItem 之后,左滑返回手势失效了,解决办法: self.navigationController.interactiveP ...

  4. VB6 代码编辑页面添加支持滚轮模式

    VB6 中的代码编辑页面默认是不支持滚轮模式的,这让在编辑代码时的体验很是不爽. 但在64位win10系统进行加载配置时,可能会出现问题,可用如下方法解决: http://download.micro ...

  5. ubuntu14.04搭建LAMP环境(nginx,php,mysql,linux)详解

    最近更换开发环境至ubuntu,整理开发环境和常用软件的安装配置(更新排版) 以下安装过程经过多次操作得出,参照步骤进行操作即可 一.LAMP基本环境搭建 1 切换root账号 sudo su 2,安 ...

  6. shell 练习题

    1.编写脚本/bin/per.sh,判断当前用户对指定参数文件,是否不可读并且不可写 read -p "Please Input A File: " file if [ ! -e ...

  7. 01、Linux介绍

    一. Linux介绍 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和 ...

  8. 我如何解决Centos下cannot find a valid baseurl for repo的问题的

    刚刚安装完centos,进入命令行模式后,发现所有的命令都不能使用,最后一行显示:Error:Cannot find a valid baseurl for repo:base,如何解决? 在cent ...

  9. 11Vim文本编辑器

    Vim文本编辑器 在Linux系统中一切都是文件,而配置一个服务就是在修改其配置文件的参数. Vim提供了三种模式:命令模式.输入模式.末行模式 1.命令模式 每次运行Vim编辑器时,默认进入命令模式 ...

  10. cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

    参考  http://blog.csdn.net/mazicwong/article/details/54946952 1.到https://curl.haxx.se/ca/cacert.pem复制下 ...