HDU 2459 Maximum repetition substring
题目:Maximum repetition substring
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2459
题意:给你一个字符串,求连续重复出现次数最多的子串(不重叠),如果有多个,输出字典序最小的那个。别如aacdabcdab,a连续着重复出现2次,cdab连续着出现2次,但aa的字典序小,所以输出aa。
思路:
枚举+后缀树组+rmq
枚举重复串的长度,后缀数组预处理出height数组,rmq预处理height,实现O(1)查询。
给几组测试数据:
1. aabababa,答案为ababab,不是bababa
2. atbctbctb,答案是bctbct,不是ctbctb
3. aabcabcabcab,答案是abcabcabc,不是cabcabcab
- #include<stdio.h>
- #include<string.h>
- #include<math.h>
- #define N 200020
- char s1[];
- int ws[N],wv[N];
- int sa[N],r[N],wx[N],wy[N];
- int height[N];
- bool cmp(int *r,int a,int b,int l)
- {
- return r[a]==r[b]&&r[a+l]==r[b+l];
- }
- void da(int *r,int n,int m)
- {
- //注意,这里的n必须比原始数组大小大1
- int *x=wx,*y=wy;
- for(int i=;i<m;i++) ws[i]=;
- for(int i=;i<n;i++) ws[x[i]=r[i]]++;
- for(int i=;i<m;i++) ws[i]+=ws[i-];
- for(int i=n-;i>=;i--) sa[--ws[x[i]]]=i;
- //这里的x[i] 表示下标i的第一关键字排名
- int i,j,p,*t;
- for(j=,p=;p<n;j*=,m=p)
- {
- for(p=,i=n-j;i<n;i++) y[p++]=i;
- for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
- //此时的y[i] 表示第二关键字排第i的下标是y[i]
- for(i=;i<n;i++) wv[i]=x[y[i]];
- for(i=;i<m;i++) ws[i]=;
- for(i=;i<n;i++) ws[wv[i]]++;
- for(i=;i<m;i++) ws[i]+=ws[i-];
- for(i=n-;i>=;i--) sa[--ws[wv[i]]]=y[i];
- for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
- x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
- }
- for(int i=;i<n;i++)
- {
- r[sa[i]]=i;
- }
- }
- void calHeight(int n)
- {
- int h=;
- for(int i=;i<n;i++)
- {
- if(r[i]==) h=;
- else
- {
- int k=sa[r[i]-];
- if(--h<) h=;
- while(s1[k+h]==s1[i+h]) h++;
- }
- height[r[i]]=h;
- }
- }
- int f[][];
- int min(int x,int y)
- {
- return x<y?x:y;
- }
- int max(int x,int y)
- {
- return x<y?y:x;
- }
- void rmq(int n)
- {
- for(int j=;j<n;j++) f[j][]=height[j];
- for(int i=;i<;i++)
- {
- for(int j=;j<n;j++)
- {
- if(j+(<<i)- < n)
- {
- f[j][i]=min(f[j][i-],f[j+(<<i-)][i-]);
- }
- }
- }
- }
- int look(int x,int y)
- {
- x=r[x];
- y=r[y];
- if(x>y) x^=y^=x^=y;
- x++;
- int k=(int)log2((double)(y-x+));
- return min(f[x][k],f[y-(<<k)+][k]);
- }
- bool cmp(int sl,int l)
- {
- if(r[sl]>r[l]) return ;
- return ;
- }
- void solve(int n)
- {
- int maxt=,sl=,sr=;
- for(int i=;i<=n/;i++)
- {
- for(int j=;j+i<n;j+=i)
- {
- int l=j;
- int r=j+i;
- int lcp=look(l,r);
- int d=lcp/i+;
- int t=j-(i-lcp%i);
- for(int k=l-;k>=&&k+i>j&&s1[k]==s1[k+i];k--)
- {
- if(k==t)
- {
- d++;
- l=k;
- }
- else if(cmp(l,k))
- {
- l=k;
- }
- }
- if(d>maxt)
- {
- sl=l;
- sr=l+d*i-;
- maxt=d;
- }
- else if(d==maxt&&cmp(sl,l))
- {
- sl=l;
- sr=l+d*i-;
- }
- }
- }
- for(int i=sl;i<=sr;i++)
- {
- printf("%c",s1[i]);
- }
- printf("\n");
- }
- int main()
- {
- int cas=;
- while(scanf("%s",s1)!=EOF)
- {
- if(s1[]=='#') break;
- int len=strlen(s1);
- for(int i=;i<len;i++)
- r[i]=s1[i]-'a'+;
- r[len++]=;
- da(r,len,);
- calHeight(len);
- rmq(len);
- printf("Case %d: ",cas++);
- solve(len-);
- }
- return ;
- }
HDU 2459 Maximum repetition substring的更多相关文章
- 【HDOJ】2459 Maximum repetition substring
后缀数组+RMQ. /* 2459 */ #include <iostream> #include <sstream> #include <string> #inc ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- Maximum repetition substring 后缀数组
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7578 Acc ...
- Maximum repetition substring (poj3693 后缀数组求重复次数最多的连续重复子串)
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6328 Acc ...
- POJ 3693 Maximum repetition substring(最多重复次数的子串)
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10461 Ac ...
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- Maximum repetition substring(POJ - 3693)(sa(后缀数组)+st表)
The repetition number of a string is defined as the maximum number \(R\) such that the string can be ...
- POJ 3693 Maximum repetition substring(后缀数组)
Description The repetition number of a string is defined as the maximum number R such that the strin ...
随机推荐
- 转://使用insert插入大量数据的总结
使用insert插入大量数据的个人经验总结在很多时候,我们会需要对一个表进行插入大量的数据,并且希望在尽可能短的时间内完成该工作,这里,和大家分享下我平时在做大量数据insert的一些经验. 前提:在 ...
- NUMA特性禁用
一.检查OS是否开启NUMA # numactl --hardware 二.Linux OS层面禁用NUMA 1.修改 grub.conf # vi /boot/grub/grub.conf #/* ...
- ESP32入门示例 - SD卡Web服务器
这个是来自ESP32官方示例的改版,官方的示例由于存在一些问题所以我进行了修改原本的示例有点逻辑上的问题,所以进行了一些修改 主要修改有:1.新增SD卡测试部分 复制自官方SD卡示例2.新增一个根目录 ...
- 利用BBED恢复数据文件头
转载请注明出处:http: @@@@@@@利用BBED模拟损坏5文件1号块(文件头) BBED block block ) Block: Dba:0x01400001 ---------------- ...
- 【转】深入理解Java:注解(Annotation)--注解处理器
https://www.cnblogs.com/peida/archive/2013/04/26/3038503.html 如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了.使用注解 ...
- AutoMapper快速上手
一.什么是AutoMapper AutoMapper是一个简单的对象映射框架(OOM),对象映射原理是把一种类型的输入对象转换为不同类型的输出对象,通俗讲就是通过一些约束讲一种类型中数据自动映射到另 ...
- 【php增删改查实例】第二十五节 - 在main.php中显示头像
在用户成功上传头像以后,用户登录系统,应该能够看到自己的头像,本节演示如何在这个地方: 添加用户头像. 1.用DIV做: border-radius:50% background:url(xxx.jp ...
- Scala学习(八)练习
Scala中继承&练习 1. 扩展如下的BankAccount类,新类CheckingAccount对每次存款和取款都收取1美元的手续费 class BankAccount ( initial ...
- .NET 框架 Microsoft .NET Framework (更新至.NET Framework4.8)
https://dotnet.microsoft.com/download/dotnet-framework 产品名称 离线安装包 .NET Framework 4.8 点击下载 .NET Frame ...
- Omi 拥抱 60FPS 的 Web 动画
写在前面 Omi 框架 正式发布了 → omi-transform. Made css3 transform super easy. Made 60 FPS easy. 作为 Omi 组件化开发特效运 ...