题目大意

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. kubernetes-深入理解pod对象(七)

    Pod中如何管理多个容器 Pod中可以同时运行多个进程(作为容器运行)协同工作.同一个Pod中的容器会自动的分配到同一个 node 上.同一个Pod中的容器共享资源.网络环境和依赖,它们总是被同时调度 ...

  2. idea spring boot启动项目上面有红色叉

    一打开IDEA,在启动debug项目有一个红色叉如下图 因为打开项目可以主项目的包没有加载进来,解决办法就是右击项目->maven->Reimport  就搞定了..

  3. c#和Java中的继承

    c#和Java: 1.首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段. 2.子类并没有继承父类的构造函数,但是.子类会默认的调用父类无参数的构造函数,创建父类对象,让子类可以使用父 ...

  4. Bootstrap历练实例:带徽章的列表组

    向列表组添加徽章 我们可以向任意的列表项添加徽章组件,它会自动定位到右边.只需要在 <li> 元素中添加 <span class="badge"> 即可.下 ...

  5. bootstrap 警告(Alerts)

    本章将讲解警告(Alerts)以及bootstrap所提供的用于警告的class类.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添 ...

  6. Bootstrap 缩略图

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  7. 遍历Map的两种方式

    取出map集合中所有元素的方式一:keySet()方法. 可以将map集合中的键都取出存放到set集合中.对set集合进行迭代.迭代完成,再通过get方法对获取到的键进行值的获取. Set keySe ...

  8. React动态import()

    React动态import() react-router@v4代码分离,推荐的import().这里分享webpack配置和使用方法. 首先安装两个必须的包 cnpm i react-loadable ...

  9. css制作三角形,下拉框三角形

    网站制作中常常需要下拉框,而如果下拉框如果只是单纯的矩形则会显得太过单调,所以这次教大家利用css制作三角形放在矩形上面 首先利用css制作三角形 div { width:0px; height:0p ...

  10. 跟踪路由 tracert

    由于最近遇到网络出现故障的问题,便使用到Tracert来确定了下出现故障的网络节点 记录下tracert命令相关内容 1. 简介 2. Tracert工作原理... 3. 常用参数 4. 使用示例与输 ...