poj 3581 后缀数组 详解

2024-05-28 05:08
文章标签 数组 详解 后缀 poj 3581

本文主要是介绍poj 3581 后缀数组 详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个题折腾了快一个月,终于今晚又奋战了4个小时,AC掉了

题目:http://poj.org/problem?id=3581

首先看我写这个后缀数组教程,其实还不错http://blog.csdn.net/u011026968/article/details/20851295

关于第一个位置,反向读入,然后求后缀数组,找最小位置就好

第二个位置比较麻烦,参考这个博客的例子:http://bbezxcy.iteye.com/blog/1420546

大致思路:

    由于需要翻转,所以在输入时就按照反序输入。比如样例输入是5     10 1 2 3 4。我们从后向前读入就变为5     4 3 2 1 10。对这列数求出后缀数组。在大于2的后最中找到最小的后缀并输出。对于剩下的前缀s,我们把s串接到自己后面,也就是ss。再对这个串求出后缀数组,然后再把s中最小的前缀输出。最后把剩下的串输出。

 

对于第二步为什么要复制剩余串接在后面,用下面案例说明

6

10 1 2 2 3 4

 

第一步翻转后得到

4 3 2 2 1 10

 

求出后缀数组后得到最小的后缀便是:1 10,将其输出

剩下来的串是 4 3 2 2.

 

我们如果直接从剩余串中找到最小后缀的话会产生以下结果。

最小后缀是 2,输出。

输出剩余串 4 3 2。

最后得到1 10 2 4 3 2  很明显是wrong的

 

 

我们把剩余的串复制到剩余串的后面。

对 4 3 2 2 4 3 2 2求出后缀数组。

得到前四个字符的最小的后缀是 2 2,输出。

输出剩余串 4 3.

得到1 10 2 2 4 3 

 

这里解释了为啥不能直接对剩下的串求后缀数组

我个人除了很多问题,,,,我再想想做个总结,随后附上


/*******************************************************/
//POJ 3581 后缀数组   by Pilgrim
//注意:1、此代码中k是全局变量 别乱用
//     2、algorithm
//     3、注意此题的字典序的定义,跟往常不一样的
//     4、因为有负数所以最小的应该是int的下限而不是0
/******************************************************/#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <vector>#define MAXN 300005*2
#define INF -200000000
//0x80000000using namespace std;int n,k,pp,mm;
int num[MAXN],rr[MAXN];
int Rank[MAXN],tmp[MAXN],sa[MAXN];bool cmpSa(int i, int j)
{if(Rank[i]!=Rank[j]){return Rank[i]<Rank[j];}else{int ik = i+k<=n?Rank[i+k]:-INF-1;int jk = j+k<=n?Rank[j+k]:-INF-1;return ik<jk;}
}bool cmpSa2(int i, int j)
{if(Rank[i]!=Rank[j]){return Rank[i]<Rank[j];}else{int ik = i+k<=pp?Rank[i+k]:-INF-1;int jk = j+k<=pp?Rank[j+k]:-INF-1;return ik<jk;}
}bool cmpSS(int i,int j)
{return rr[i]<rr[j];
}void con_sa(int s,int e)
{int i,j;//sort(tmp+s,tmp+e+1,cmpSS);for(i=s;i<=e;i++)Rank[i]=rr[i];Rank[e]=INF;//printf("%d tmp=%d rank=%d\n",i,tmp[i],Rank[tmp[i]]);/*此时的rank已经能表示相对大小*/for(k=1;k<=e;k*=2){if(mm){pp=e;sort(sa+s,sa+e+1,cmpSa2);}else{sort(sa+s,sa+e+1,cmpSa);}tmp[sa[s]]=s;for(i=s+1;i<=e;i++){tmp[sa[i]]=tmp[sa[i-1]]+(cmpSa(sa[i-1],sa[i])?1:0);}for(i=s;i<=e;i++)Rank[i]=tmp[i];}
}void show(int p1,int p2)
{for(int i=p1;i<n;i++)printf("%d\n",num[i]);for(int i=p2;i<p1;i++)printf("%d\n",num[i]);for(int i=0;i<p2;i++)printf("%d\n",num[i]);
}void Init()
{memset(tmp,0,sizeof(tmp));memset(Rank,0,sizeof(Rank));memset(sa,0,sizeof(sa));for(int i=0;i<n;i++){scanf("%d",&num[i]);rr[n-i-1] = num[i];/*rr是整个反转后的串,*/sa[i]=i;}sa[n]=n;for(int i=0;i<=n;i++){num[i]=rr[i];tmp[i]=i;}
}void Init2(int e)
{memset(tmp,0,sizeof(tmp));memset(Rank,0,sizeof(Rank));memset(sa,0,sizeof(sa));for(int i=0;i<e;i++){rr[i+e] = rr[i];}for(int i=e*2;i<=2*n;i++)rr[i]=INF;for(int i=0; i<=e*2; i++){sa[i]=tmp[i]=i;tmp[i]=i;}
}int main()
{//freopen("poj 3581.txt","r",stdin);int p1,p2;scanf("%d",&n);mm=0;Init();con_sa(0,n);for(int i=0;i<=n;i++){p1=sa[i];if(p1>=2 && p1<n)break;}mm=1;Init2(p1);con_sa(0,p1*2);for(int i=0; i<=p1*2;i++){p2=sa[i];if(p2>=1 && p2<p1)break;}show(p1,p2);return 0;
}



这篇关于poj 3581 后缀数组 详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1009618

相关文章

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor

一文深入详解Python的secrets模块

《一文深入详解Python的secrets模块》在构建涉及用户身份认证、权限管理、加密通信等系统时,开发者最不能忽视的一个问题就是“安全性”,Python在3.6版本中引入了专门面向安全用途的secr... 目录引言一、背景与动机:为什么需要 secrets 模块?二、secrets 模块的核心功能1. 基

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字