POJ - 3693 Maximum repetition substring(重复次数最多的连续重复子串)
传送门:POJ - 3693
题意:给你一个字符串,求重复次数最多的连续重复子串,如果有一样的,取字典序小的字符串。
题解:
比较容易理解的部分就是枚举长度为L,然后看长度为L的字符串最多连续出现几次。既然长度为L的串重复出现,那么str[0],str[l],str[2*l]……中肯定有两个连续的出现在字符串中。
那么就枚举连续的两个,然后从这两个字符前后匹配,看最多能匹配多远。即以str[i*l],str[i*l+l]前后匹配,这里是通过查询suffix(i*l),suffix(i*l+l)的最长公共前缀。通过rank值能找到i*l,与i*l+l的排名,我们要查询的是这段区间的height的最小值,通过RMQ预处理达到查询为0(1)的复杂度
设LCP长度为M, 则答案显然为M / L + 1, 但这不一定是最好的, 因为答案的首尾不一定再我们枚举的位置上. 我的解决方法是, 我们考虑M % L的值的意义, 我们可以认为是后面多了M % L个字符, 但是我们更可以想成前面少了(L - M % L)个字符! 所以我们求后缀j * L - (L - M % L)与后缀(j+ 1) * L - (L - M % L)的最长公共前缀。即把之前的区间前缀L-M%L即可。
然后把可能取到最大值的长度L保存,由于 题目要求字典序最小,通过sa数组进行枚举,取到的第一组,肯定是字典序最小的。
题解的出处:https://blog.csdn.net/acm_cxlove/article/details/7941205
1 #include<cstdio>
2 #include<algorithm>
3 #include<queue>
4 #include<iostream>
5 #include<cmath>
6 #include<cstring>
7 using namespace std;
8
9 const int maxn = 1e5+10;
10 int wa[maxn],wb[maxn],wsf[maxn],wv[maxn],sa[maxn];
11 int rnk[maxn],height[maxn];
12 char s[maxn];
13 int r[maxn];
14
15 //sa:字典序中排第i位的起始位置在str中第sa[i] sa[1~n]为有效值
16
17 //rnk:就是str第i个位置的后缀是在字典序排第几 rnk[0~n-1]为有效值
18
19 //height:字典序排i和i-1的后缀的最长公共前缀 height[2~n]为有效值,第二个到最后一个
20
21 int cmp(int *r,int a,int b,int k)
22 {
23 return r[a]==r[b]&&r[a+k]==r[b+k];
24 }
25
26 void getsa(int *r,int *sa,int n,int m)//n为添加0后的总长
27 {
28 int i,j,p,*x=wa,*y=wb,*t;
29 for(i=0; i<m; i++) wsf[i]=0;
30 for(i=0; i<=n; i++) wsf[x[i]=r[i]]++;
31 for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
32 for(i=n; i>=0; i--) sa[--wsf[x[i]]]=i;
33 p=1;
34 j=1;
35 for(; p<=n; j*=2,m=p){
36 for(p=0,i=n+1-j; i<=n; i++) y[p++]=i;
37 for(i=0; i<=n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
38 for(i=0; i<=n; i++) wv[i]=x[y[i]];
39 for(i=0; i<m; i++) wsf[i]=0;
40 for(i=0; i<=n; i++) wsf[wv[i]]++;
41 for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
42 for(i=n; i>=0; i--) sa[--wsf[wv[i]]]=y[i];
43 swap(x,y);
44 x[sa[0]]=0;
45 for(p=1,i=1; i<=n; i++)
46 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;
47 }
48 }
49
50 void getheight(int *r,int n)//n为添加0后的总长
51 {
52 int i,j,k=0;
53 for(i=1; i<=n; i++) rnk[sa[i]]=i;
54 for(i=0; i<n; i++){
55 if(k)
56 k--;
57 else
58 k=0;
59 j=sa[rnk[i]-1];
60 while(r[i+k]==r[j+k])
61 k++;
62 height[rnk[i]]=k;
63 }
64 }
65
66 int dp[maxn][40];
67
68 void rmq_init(int n){
69
70 int m=floor(log(n+0.0)/log(2.0));
71 for(int i=1;i<=n;i++)dp[i][0]=height[i];
72 for(int j=1;j<=m;j++){
73 for(int i=n;i;i--){
74 dp[i][j]=dp[i][j-1];
75 if(i+(1<<(j-1))<=n){
76 dp[i][j]=min(dp[i][j],dp[i+(1<<(j-1))][j-1]);
77 }
78 }
79 }
80 }
81
82 int rmq(int l,int r){
83
84 int a=rnk[l],b=rnk[r];
85 if(a>b)swap(a,b);
86 a++;
87 int k=floor(log(b-a+1.0)/log(2.0));
88 return min(dp[a][k],dp[b-(1<<k)+1][k]);
89 }
90
91 int main()
92 {
93 ios::sync_with_stdio(false);
94 cin.tie(0);
95 cout.tie(0);
96 int t=1;
97 while(cin>>s){
98 if(s[0]=='#') break;
99 int len=strlen(s);
100 for(int i=0;i<len;i++) r[i]=s[i]-'a'+1;
101 r[len]=0;
102 getsa(r,sa,len,150);
103 getheight(r,len);
104 rmq_init(len);
105 int ans=0;
106 int pos=0,p=0;
107 for(int k=1;k<len;k++){ //枚举长度
108 for(int i=0;i+k<len;i+=k){ //第i段
109 int n=rmq(i,i+k); //每一段的公共前缀最小值
110 n--;
111 for(int j=0;j<=k-1;j++){ //枚举每一段的起点
112 int now=i-j;
113 if((now<0||s[now]!=s[now+k])&&j) break;
114 n++;
115 int sum=n/k+1;
116 if(sum>ans||(sum==ans&&rnk[now]<rnk[pos])){
117 ans=sum;
118 pos=now;
119 p=k;
120 }
121 }
122 }
123 }
124 cout<<"Case "<<t++<<": ";
125 if(ans<=1){
126 char tmp='z';
127 for(int i=0;i<len;i++) tmp=min(tmp,s[i]);
128 cout<<tmp<<endl;
129 }
130 else{
131 for(int i=0;i<ans*p;i++){
132 cout<<s[i+pos];
133 }
134 cout<<endl;
135 }
136 }
137 return 0;
138 }
POJ - 3693 Maximum repetition substring(重复次数最多的连续重复子串)的更多相关文章
- 【POJ 3693】Maximum repetition substring 重复次数最多的连续重复子串
后缀数组的论文里的例题,论文里的题解并没有看懂,,, 求一个重复次数最多的连续重复子串,又因为要找最靠前的,所以扫的时候记录最大的重复次数为$ans$,扫完后再后从头暴力扫到尾找重复次数为$ans$的 ...
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- POJ 3693 Maximum repetition substring(连续重复子串)
http://poj.org/problem?id=3693 题意:给定一个字符串,求重复次数最多的连续重复子串. 思路: 这道题确实是搞了很久,首先枚举连续子串的长度L,那么子串肯定包含了r[k], ...
- poj 3693 后缀数组 重复次数最多的连续重复子串
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8669 Acc ...
- POJ 3693 Maximum repetition substring(后缀数组)
Description The repetition number of a string is defined as the maximum number R such that the strin ...
- POJ-3693-Maximum repetition substring(后缀数组-重复次数最多的连续重复子串)
题意: 给出一个串,求重复次数最多的连续重复子串 分析: 比较容易理解的部分就是枚举长度为L,然后看长度为L的字符串最多连续出现几次. 既然长度为L的串重复出现,那么str[0],str[l],str ...
- 后缀数组 POJ 3693 Maximum repetition substring
题目链接 题意:给定一个字符串,求重复次数最多的连续重复子串. 分析:(论文上的分析)先穷举长度 L,然后求长度为 L 的子串最多能连续出现几次.首先连续出现 1 次是肯定可以的,所以这里只考虑至少 ...
- spoj687 后缀数组重复次数最多的连续重复子串
REPEATS - Repeats no tags A string s is called an (k,l)-repeat if s is obtained by concatenating k& ...
- SPOJ - REPEATS —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/SPOJ-REPEATS REPEATS - Repeats no tags A string s is called an (k,l ...
随机推荐
- http-请求和响应报文的构成
请求的构成: 1)请求方法URI协议/版本 2)请求头(Request Header) 3)请求正文 1)请求方法URI协议/版本 Request URL: http://localhost:8080 ...
- Hbase Region合并
业务场景: Kafka+SparkStreaming+Hbase由于数据大量的迁移,再加上业务的改动,新增了很多表,导致rerigon总数接近4万(36个节点) 组件版本: Kafka:2.1.1 S ...
- memcached+magent的集群部署详细过程
问题描述 Memcached在实现分布集群部署时, Memcached服务端的之间是没有通讯的,服务端是伪分布式,实现分布式是由客户端实现的,客户端实现了分布式算法把数据保存到不同的Memcached ...
- 视频画面中实现人脸遮挡教程 - 基于 TensorFlow 实现
在进行视频通话时,我们往往需要对画面进行一些实时分析,例如识别画面里的人.车.动物等等.这节里我们将使用时信魔方的人脸监视模块实现人脸被手部遮挡的检测,如下图所示效果: 预备知识 时信魔方的客户端使用 ...
- 性能测试工具locust简单应用
简介 Locust是一种易于使用的分布式用户负载测试工具.可用于对网站(或系统)负载测试,并依据响应数据计算出系统支持的并发用户数. 安装及调试(以下操作在windows环境下进行) Locust基于 ...
- ES数据库高可用配置
ES高可用集群部署 1.ES高可用架构图 2.创建ES用户组 1.Elasticsearch不能在 root 用户下启动,我们需要在三台机器上分创建一个普通用户# 创建elastic用户 userad ...
- jQuery json遍历渲染到页面并且拼接html
jQuery 处理 json遍历在页面中显示,并且拼接html. 1 <title>json多维数组遍历渲染</title> 2 3 <body> 4 <di ...
- GRPC Health Checking Protocol Unavailable 14
https://github.com/grpc/grpc/blob/master/doc/health-checking.md GRPC Health Checking Protocol Health ...
- 【练习】goroutine chan 通道 总结
1. fatal error: all goroutines are asleep - deadlock! 所有的协程都休眠了 - 死锁! package mainimport("fmt&q ...
- Defining Go Modules
research!rsc: Go & Versioning https://research.swtch.com/vgo shawn@a:~/gokit/tmp$ go get --helpu ...