BZOJ2803[Poi2012]Prefixuffix——hash

BZOJ2803[Poi2012]Prefixuffix——hash

题目描述

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

输入

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

输出

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

样例输入

15
ababbabababbaab

样例输出

6
 
假设两个串是循环同构的,那么这两个串可以表示成x+y和y+x的形式(其中x,y为两个字符串)
设f[i]表示前后都去掉i个字符后能匹配的最长前后缀长度,即y的最长长度。
手画一下能够发现对于位于左一半的i和i+1,f[i]<=f[i+1]+2。如果大于了就说明f[i+1]还能更大。
那么就可以从中间向开头转移f[i],最后求出i+f[i]的最大值即可。这道题卡自然溢出。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll h[1000010];
ll g[1000010];
ll base1[1000010];
ll base2[1000010];
char ch[1000010];
int mod=1e9+7;
int n;
int f[1000010];
int ans=0;
bool check(int x,int y,int l)
{
    ll s1,s2,t1,t2;
    s1=((h[x+l-1]-h[x-1]*base1[l])%mod+mod)%mod;
    s2=((g[x+l-1]-g[x-1]*base2[l])%mod+mod)%mod;
    t1=((h[y+l-1]-h[y-1]*base1[l])%mod+mod)%mod;
    t2=((g[y+l-1]-g[y-1]*base2[l])%mod+mod)%mod;
    if(s1==t1&&s2==t2)
    {
        return true;
    }
    return false;
}
int main()
{
    scanf("%d",&n);
    scanf("%s",ch+1);
    base1[0]=1;
    base2[0]=1;
    for(int i=1;i<=n;i++)
    {
        base1[i]=base1[i-1]*233%mod;
        base2[i]=base2[i-1]*2333%mod;
        h[i]=(h[i-1]*233+(ch[i]-96))%mod;
        g[i]=(g[i-1]*2333+(ch[i]-96))%mod;
    }
    for(int i=n/2;i>=1;i--)
    {
        f[i]=min(f[i+1]+2,(n-2*i)/2);
        while(f[i]&&(!check(i+1,n-f[i]+1-i,f[i])))
        {
            f[i]--;
        }
    }
    for(int i=1;i<=n/2;i++)
    {
        if(!check(1,n-i+1,i))
        {
            continue;
        }
        ans=max(ans,f[i]+i);
    }
    printf("%d",ans);
}

转载于:https://www.cnblogs.com/Khada-Jhin/p/9637166.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101431.html原文链接:https://javaforall.net

(0)
上一篇 2021年6月12日 下午5:00
下一篇 2021年6月12日 下午6:00


相关推荐

  • .NET中pdb文件的作用是什么「建议收藏」

    .NET中pdb文件的作用是什么「建议收藏」.PDB是ProgramDatabase的缩写,全称为“程序数据库”文件。我们使用它(更确切的说是看到它被应用)大多数场景是调试应用程序。目前我们对.PDB文件的普遍认知是它存储了被编译文件的调试信息,作为符号文件存在。 PDB文件寻路 如果我们观察VS启动调试加载模块和符号文件的过程,会发现它通常会从可执行文件或者DLL文件的相同目录中加载符号文件。这正是调试器寻找PDB文件的

    2022年5月5日
    117
  • 在pycharm中使用tensorflow_使用中是什么意思

    在pycharm中使用tensorflow_使用中是什么意思QtDesigner的介绍在PyQt中编写UI界面可以直接通过代码来实现,也可以通过QtDesigner来完成。QtDesigner的设计符合MVC的架构,其实现了视图和逻辑的分离,从而实现了开发的便捷。QtDesigner中的操作方式十分灵活,其通过拖拽的方式放置控件可以随时查看控件效果。QtDesigner生成的.ui文件(实质上是XML格式的文件)也可以通过pyuic5工具转换成…

    2022年8月28日
    4
  • Json 作为ActionResutl 时出错

    Json 作为ActionResutl 时出错

    2021年8月23日
    69
  • 计算机按位取反[通俗易懂]

    计算机按位取反[通俗易懂]取反过程1.转成二进制2.取补码3.补码的反码(符号位不变)4.反码加+1可以通过原码、反码和补码三者的含义及关系来介绍三者之间的换算关系:1、原码原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。比如如果是8位二进制:[+1]原=00000001[-1]原=10000001第一位是符号位。2、反码

    2022年8月14日
    5
  • JavaScript、ES5和ES6的介绍和区别

    JavaScript、ES5和ES6的介绍和区别30 分钟掌握 ES6 ES2015 核心内容 上 JavaScript ES5 和 ES6 的介绍和区别 JavaScript 简介 JavaScript 一种动态类型 弱类型 基于原型的客户端脚本语言 用来给 HTML 网页增加动态功能 JavaScript 由三部分组成 ECMAScript 核心 DOM 文档对象模型 BOM 浏览器对象模型 ECMAScript 作为核心 规定了语言的组成部

    2026年3月18日
    2
  • 软件著作权说明书模板_软件设计方案怎么写

    软件著作权说明书模板_软件设计方案怎么写1.引言1.1编写目的1.2项目背景1.2项目概要总体要求2.1系统功能概述2.2系统功能要求软件开发3.1软件需求分析3.2软件的概要设计3.2.1软件概要设计说明3.2.3基本设计概念和处理流程3.3软件的详细设计3.3.1系统结构3.3.2模块设计说明3.3.3爬虫模块3.3.4日志模块3.3.5数…

    2026年2月16日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号