POJ-3693 Maximum repetition substring 后缀数组

  题目链接:http://poj.org/problem?id=3693

  求字符串的重复次数最多的且字典序最小的字串。

  很不错的题目。罗穗骞大牛论文的模板题,摘了Neo / Add ~0U>>1大牛的详细题解,如下:

  首先求第一问最大重复数。从N的范围来看O(N^2)虽不靠谱,但是起码能带来些有用的启示。方法有二,一是枚举开头位置求重复长度;二是枚举重复长度求开头位置。

第一种方法求最大重复数的方法MS也只有枚举重复长度然后去判……所以说我们从第二个方法入手。O(N^2)的方法是再枚举开头位置。我们来考虑一下能不能少枚举一些开头位置——更确切地说,能不能只枚举一些特殊位置,设当前枚举的长度为L,能不能只枚举0,L,2L,……这样的位置。见下图:

                         

  首先明确,枚举长度Len的时候,从一个位置求出的Lcp值表明从此处开始重复数为floor(Lcp / Len) + 1。

  然后容易发现的问题就是,可能从某个枚举位置向前移动“一点”能够多一个周期,从而使重复数增加。从图上来看,这种状况发生的条件就是Lcp比满足这个重复数“必需的Lcp”要多,也就是Lcp % Len ≠ 0。不难发现,这时候我们向前移动Len - Lcp % Len的话,如果有下一个周期就会进去,否则也不会引起新的变化。所以说这种方法可行。

  这样的话复杂度为n(1 + 1/2 + 1/3 + ... + 1/n) = O(nlogn)。有一个显而易见的优化,那就是只需要枚举到floor(n / 2)即可。但是后面的部分也少不了多少……

  第二问是求最小字典序的答案。我采用了这样一种方法,那就是在第一步中记录能够达到最大重复数的重复长度的集合,然后按照sa[1],sa[2],sa[3],……的顺序去暴力枚举,每到一个位置就从小到大地判重复长度的集合中有没有可行的,如果有一个可行的就立即输出结果并退出。这样的做法能够保证正确性,虽然最坏情况下仍然有可能退化到O(n^2),但是要构造这样一组数据是比较困难的(得一直枚举到最后一个后缀,还得从1到Len / 2都能满足最大重复数)。对于非特殊构造的数据这一步的复杂度几乎是O(n),于是这个题就可以水过了。

  我的代码:

  1 //STATUS:C++_AC_422MS_11232KB
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 #include<math.h>
  6 #include<iostream>
  7 #include<string>
  8 #include<algorithm>
  9 #include<vector>
 10 #include<queue>
 11 #include<stack>
 12 #include<map>
 13 using namespace std;
 14 #define LL __int64
 15 #define pii pair<int,int>
 16 #define mem(a,b) memset(a,b,sizeof(a))
 17 #define lson l,mid,rt<<1
 18 #define rson mid+1,r,rt<<1|1
 19 #define PI acos(-1.0)
 20 const int N=100010,INF=0x3f3f3f3f,MOD=10000,STA=8000010;
 21 //const LL LNF=0x3f3f3f3f3f3f3f3f;
 22 const double DNF=1e13;
 23 //
 24 inline int Max(int a,int b){return a>b?a:b;}
 25 inline int Min(int a,int b){return a<b?a:b;}
 26 void swap(int& a,int& b){int t=a;a=b;b=t;}
 27 void swap(LL& a,LL& b){LL t=a;a=b;b=t;}
 28 //
 29 
 30 char s[N];
 31 int d[N][20];
 32 int num[N];
 33 int sa[N],t1[N],t2[N],c[N],rank[N],height[N];
 34 int n,m;
 35 
 36 void build_sa(int s[],int n,int m)
 37 {
 38     int i,k,p,*x=t1,*y=t2;
 39     //第一轮基数排序
 40     for(i=0;i<m;i++)c[i]=0;
 41     for(i=0;i<n;i++)c[x[i]=s[i]]++;
 42     for(i=1;i<m;i++)c[i]+=c[i-1];
 43     for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
 44     for(k=1;k<=n;k<<=1){
 45         p=0;
 46         //直接利用sa数组排序第二关键字
 47         for(i=n-k;i<n;i++)y[p++]=i;
 48         for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
 49         //基数排序第一关键字
 50         for(i=0;i<m;i++)c[i]=0;
 51         for(i=0;i<n;i++)c[x[y[i]]]++;
 52         for(i=1;i<m;i++)c[i]+=c[i-1];
 53         for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
 54         //根据sa和x数组计算新的x数组
 55         swap(x,y);
 56         p=1;x[sa[0]]=0;
 57         for(i=1;i<n;i++)
 58             x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
 59         if(p>=n)break;   //已经排好序,直接退出
 60         m=p;     //下次基数排序的最大值
 61     }
 62 }
 63 
 64 void getHeight(int s[],int n)
 65 {
 66     int i,j,k=0;
 67     for(i=0;i<=n;i++)rank[sa[i]]=i;
 68     for(i=0;i<n;i++){
 69         if(k)k--;
 70         j=sa[rank[i]-1];
 71         while(s[i+k]==s[j+k])k++;
 72         height[rank[i]]=k;
 73     }
 74 }
 75 
 76 void rmq_init(int a[])
 77 {
 78     int i,j;
 79     for(i=1;i<=n;i++)d[i][0]=a[i];
 80     for(j=1;(1<<j)<=n;j++){
 81         for(i=1;i+(1<<j)-1<=n;i++){
 82             d[i][j]=Min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
 83         }
 84     }
 85 }
 86 
 87 int rmq(int l,int r)
 88 {
 89     int k=0;
 90     while((1<<(k+1))<=r-l+1)k++;
 91     return Min(d[l][k],d[r-(1<<k)+1][k]);
 92 }
 93 
 94 int lcp(int a,int b)
 95 {
 96     if(a==b)return n-a;
 97     int ra=rank[a],rb=rank[b];
 98     if(ra>rb)swap(ra,rb);
 99     ra++;
100     return rmq(ra,rb);
101 }
102 
103 int main()
104 {
105  //   freopen("in.txt","r",stdin);
106     int i,j,sz=1,hig,ans[N],cnt,fre,wide,t,ss,ok;
107     while(~scanf("%s",s) && (s[0]!='#' || s[1]) )
108     {
109         n=strlen(s);
110         for(i=0;i<n;i++){
111             num[i]=s[i]-'a'+1;
112         }
113         num[n]=0;
114         m=27;
115         build_sa(num,n+1,m);
116         getHeight(num,n);
117         rmq_init(height);
118 
119         hig=0;
120         for(i=1;i<=n/2;i++){
121             for(j=0;j+i<n;j+=i){
122                 wide=lcp(j,j+i);
123                 fre=wide/i+1;
124                 t=j-(i-wide%i);
125                 if(t>=0 && wide%i){
126                     wide=lcp(t,t+i);
127                     fre=Max(fre,wide/i+1);
128                 }
129                 if(fre>hig){
130                     hig=fre;
131                     cnt=0;
132                     ans[cnt++]=i;
133                 }
134                 else if(fre==hig){
135                     ans[cnt++]=i;
136                 }
137             }
138         }
139 
140         ok=0;
141         for(i=1;i<=n;i++){
142             for(j=0;j<cnt;j++){
143                 if(sa[i]+ans[j]>=n)continue;
144                 wide=lcp(sa[i],sa[i]+ans[j]);
145                 if(wide/ans[j]+1==hig){
146                     ss=sa[i];
147                     s[ss+hig*ans[j]]=0;
148                     ok=1;
149                     break;
150                 }
151             }
152             if(ok)break;
153         }
154 
155         printf("Case %d: %s\n",sz++,s+ss);
156     }
157     return 0;
158 }

 

转载于:https://www.cnblogs.com/zhsl/archive/2013/04/24/3040629.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433649.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python nlp_Python NLP入门教程

本文简要介绍Python自然语言处理(NLP)&#xff0c;使用Python的NLTK库。NLTK是Python的自然语言处理工具包&#xff0c;在NLP领域中&#xff0c;最常使用的一个Python库。 什么是NLP&#xff1f; 简单来说&#xff0c;自然语言处理(NLP)就是开发能够理解人类语言的应用程序或服…

python安装后cmd找不到_关于Python3.6环境中,virtualenv找不到命令的解决方法

今天收到一个网友的提问,说是,已经安装好了,Python3.6,系统环境变量也检查过,没有问题,在系统CMD命令行窗口,输入python可以返回当前安装的python环境的版本号,如下图python3.6 也测试了pip安装程序,也是正常的,然后用pip install virtualenv 安装虚拟环境,整个过程也没有报错,…

Mybatis占位符问题—ReflectionException: There is no getter for property named xxx

使用${}占位符时&#xff08;PS&#xff1a;一般都使用#{}&#xff0c;不建议使用${}&#xff09;&#xff0c;发现xml文件中的SQL语句使用了$后会报错&#xff1a;具体情况如下&#xff1a;解决方案如下&#xff1a;在参数前加上Param("id")注解

kamailio,asteisk,realtime 实现负载均衡(集群)完整配置笔记

环境 负载均衡数据库服务器 Centos-5.4 kamailio-3.1.4 mysql-5.0.77-4.el5_6.6 IP:192.168.1.30 asterisk服务器1 Centos-5.4 asterisk-1.8 IP:192.168.1.31 asterisk服务器2 Centos-5.4 asterisk-1.8 IP:192.168.1.32 目的 1&#xff1a;假设一个简易的asterisk 集…

maven依赖 spark sql_window环境运行spark-xgboost 8.1踩到的坑

在window 环境下使用spark - xgboost会出现一些问题&#xff0c;这里记录一下。环境&#xff1a;window 7 spark 2.31 xgboost 8.1 idea maven一.依赖以及代码数据集下载地址UCI Machine Learning Repository: Iris Data Set​archive.ics.uci.edupom依赖<!-- https://m…

python书籍排行榜前十名_学习Python,这些书你看过几本?

Python是一门简单&#xff0c;强大的计算机编程语言。Python书也是种类繁多&#xff0c;对于初学者选择合适的学习书籍是很有必要的。 1、Python编程&#xff1a;从入门到实践 全书分两部分&#xff1a;第一部分介绍用Python编程所必须了解的基本概念&#xff1b;第二部分将理论…

MyBatis笔记——配置文件完成增删改查

l 完成品牌数据的增删改查操作 要完成的功能列表清单&#xff1a;□ 查询 查询所有数据 查看详情 条件查询□ 添加□ 修改 修改全部字段 修改动态字段□ 删除 删除一个 批量删除准备环境&#xff1a; 数据库表tb_branddrop table if exists tb_brand;CREATE TABLE tb_brand(--…

web——Tomcat Maven插件及Servlet入门

• IDEA中使用Tomcat-Tomcat Maven插件 ○ Pom.xml添加Tomcat插件<build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version><!--&…

外架小横杆外露长度规范要求_安全文明施工规范

分类规范内容内外架安全1、扫地杆离地0.2米&#xff0c;立杆间距1.5米&#xff0c;外大横杆上下间距1米&#xff0c;内大横杆上下间距1.8米&#xff0c;步距1.8米2、立杆着落点不得悬空&#xff0c;垫块面积&#xff1e;240240mm3、外架和支模架不得连接、固定在一起4、外架操作…

java 邮件模板_Spring Boot 2发送邮件手把手图文教程

点击上方 IT牧场 &#xff0c;选择 置顶或者星标技术干货每日送达&#xff01;本文基于&#xff1a;Spring Boot 2.1.3&#xff0c;理论支持Spring Boot 2.x所有版本。最近有童鞋问到笔者如何用Spring Boot发送邮件&#xff0c;故而整理下Spring Boot发送邮件的各种姿势。说到邮…

Web——Request请求

•Request通用方式获取请求参数 ○ 请求参数获取方式&#xff1a; GET方式&#xff1a;□ String getQueryString() POST方式&#xff1a;□ BufferedReader getReader()○ 通用方式&#xff1a; Map<String, String[]> getParameterMap()//获取所有参数Map集合 String[]…

mfc点击按钮让对话框关闭_WinXP系统开始菜单中关机按钮消失的恢复教程

WinXP系统开始菜单里面的关机按钮不见了怎么办&#xff1f;最近有用户反映&#xff0c;打开WinXP系统的开始菜单准备关机时&#xff0c;却发现无法关机了&#xff0c;开始菜单里面没有关机按钮&#xff0c;这是怎么回事&#xff1f;本文就为大家介绍XP系统恢复开始菜单关机按钮…

马逊s3云存储接口_当对象存储“湖”有了强一致性

从 2006年第一个云服务对象存储服务 Amazon S3 发布直到 2020年12月1日之前&#xff0c;S3 对象操作都是遵循 “最终一致性”原则&#xff0c;对象存储服务本身就是一个复杂的分布式系统&#xff0c;但对用户暴露简单的 API 服务接口&#xff0c;无限扩展存储大小&#xff0c;极…

Web——Request转发和Response重定向

• Request请求转发 ○ 请求转发 请求转发&#xff08;forward&#xff09;&#xff1a;一种在服务器内部的资源跳转方式 ○ 实现方式&#xff1a; request.getRequestDispatcher("资源B路径").forward(request,response);○ 请求转发资源间共享数据&#xff1a;使用…

if else if语句格式_闲话Python之条件语句IF

我发现好像哪里都会有if&#xff0c;下面就来聊聊Python当中if的常见用法。最简单的格式就是&#xff0c;只有一个if&#xff0c;比如下面这个&#xff1a;my_deposit代码中的my_deposit50000等效于my_depositmy_deposit50000his_deposit-50000则等效于his_deposithis_deposit-…

delphi下实现ribbon界面的方法(一)

delphi下实现ribbon界面的方法&#xff08;一&#xff09; office 2007和2010是现在大多数人经常使用的办公软件&#xff0c;几乎每天都在使用。因此&#xff0c;在软件中如果使用类office的界面样式&#xff0c;客户用着非常习惯&#xff0c;而且学习曲线低&#xff0c;office…

Web笔记——Filter过滤器

○ 概念&#xff1a;Filter表示过滤器&#xff0c;是JavaWeb三大组件(Servlet、Filter、Listener)之一。 ○ 过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。 ○ 过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;权限控制、统一编码处理、敏感…

mysql修改语句_序言:MySQL与Navicat安装Tips

一、数据库相关的基础知识1.1 数据分析师主要集中在select高效查找上&#xff0c;纯粹的底层运维就不需要太关注&#xff1b;1.2 数据库与表类比sheet是表&#xff0c;整个Excel文件是一个数据库&#xff1b;1.3 行与列1.4 主键&#xff08;人的身份证&#xff09;表的主键不做…

java office文件加水印_永中Office与统一操作系统UOS完成适配,开辟高效智能办公新领域...

近日&#xff0c;永中Office办公软件完成了与统一操作系统UOS的适配工作&#xff0c;此次成功适配表明信息技术应用创新操作系统与办公软件兼容性能优良、运行稳定&#xff0c;大幅提升用户在信创计算机上的办公体验&#xff0c;可为政企提供安全可靠的IT环境。永中Office是由永…

c3p0依赖导入失败问题

今天在学习c3p0的时侯&#xff0c;导入依赖后变红然后去maven仓库[&#xff08;https://mvnrepository.com/artifact/com.mchange/c3p0&#xff09;]中找&#xff0c;发现是groupId的问题。 更改后正常