POJ 3693 Maximum repetition substring(后缀数组求最长重复子串)
来源:互联网 发布:吃鸡好玩在哪 知乎 编辑:程序博客网 时间:2024/04/29 18:20
题目大意:和spoj687类似,就是当长度相同是需要输出一个最小的字典序的序列。
解体思路:这次需要枚举所有的从i到d = i-L/i (d = i-L%i)的位置,然后记录保证最大值的同时,求出来字典序最小的。
Description
The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same consecutive substrings. For example, the repetition number of "ababab" is 3 and "ababa" is 1.
Given a string containing lowercase letters, you are to find a substring of it with maximum repetition number.
Input
The input consists of multiple test cases. Each test case contains exactly one line, which
gives a non-empty string consisting of lowercase letters. The length of the string will not be greater than 100,000.
The last test case is followed by a line containing a '#'.
Output
For each test case, print a line containing the test case number( beginning with 1) followed by the substring of maximum repetition number. If there are multiple substrings of maximum repetition number, print the lexicographically smallest one.
Sample Input
ccabababcdaabbccaa#
Sample Output
Case 1: abababCase 2: aa
#include <algorithm>#include <iostream>#include <stdlib.h>#include <string.h>#include <iomanip>#include <stdio.h>#include <string>#include <queue>#include <cmath>#include <stack>#include <ctime>#include <map>#include <set>#define eps 1e-9///#define M 1000100///#define LL __int64#define LL long long///#define INF 0x7ffffff#define INF 0x3f3f3f3f#define PI 3.1415926535898#define zero(x) ((fabs(x)<eps)?0:x)#define mod 1000000007#define Read() freopen("autocomplete.in","r",stdin)#define Write() freopen("autocomplete.out","w",stdout)#define Cin() ios::sync_with_stdio(false)using namespace std;inline int read(){ char ch; bool flag = false; int a = 0; while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-'))); if(ch != '-') { a *= 10; a += ch - '0'; } else { flag = true; } while(((ch = getchar()) >= '0') && (ch <= '9')) { a *= 10; a += ch - '0'; } if(flag) { a = -a; } return a;}void write(int a){ if(a < 0) { putchar('-'); a = -a; } if(a >= 10) { write(a / 10); } putchar(a % 10 + '0');}const int maxn = 100050;int wa[maxn], wb[maxn], wv[maxn], ws1[maxn];int sa[maxn];int 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 *sa, int n, int m){ int i, j, p, *x = wa, *y = wb; for(i = 0; i < m; i++) ws1[i] = 0; for(i = 0; i < n; i++) ws1[x[i] = r[i]]++; for(i = 1; i < m; i++) ws1[i] += ws1[i-1]; for(i = n-1; i >= 0; i--) sa[--ws1[x[i]]] = i; for(j = 1, p = 1; p < n; j <<= 1, m = p) { for(p = 0, i = n-j; i < n; i++) y[p++] = i; for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j; for(i = 0; i < n; i++) wv[i] = x[y[i]]; for(i = 0; i < m; i++) ws1[i] = 0; for(i = 0; i < n; i++) ws1[wv[i]]++; for(i = 1; i < m; i++) ws1[i] += ws1[i-1]; for(i = n-1; i >= 0; i--) sa[--ws1[wv[i]]] = y[i]; for(swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; i++) x[sa[i]] = cmp(y, sa[i-1], sa[i], j)?p-1:p++; }}int rank[maxn], height[maxn];void calheight(int *r, int *sa, int n){ int i, j, k = 0; for(i = 1; i <= n; i++) rank[sa[i]] = i; for(int i = 0; i < n; height[rank[i++]] = k) for(k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++); return ;}int dp[maxn][30];void RMQ(int len){ for(int i = 1; i <= len; i++) dp[i][0] = height[i]; for(int j = 1; 1<<j <= maxn; j++) { for(int i = 1; i+(1<<j)-1 <= len; i++) dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]); }}int lg[maxn];int querry(int l, int r){ int k = lg[r-l+1]; return min(dp[l][k], dp[r-(1<<k)+1][k]);}void init(){ lg[0] = -1; for (int i = 1; i < maxn; ++i) lg[i] = lg[i>>1] + 1;}int seq[maxn];char str[maxn];void Del(int n, int Case){ int Max = 0; string tmx, tmp; for(int i = 1; i <= n/2; i++) { for(int j = 0; i*j+i < n; j++) { int l = rank[i*j]; int r = rank[i*j+i]; if(l > r) swap(l, r); int x = querry(l+1, r); int y = 0; if(Max <= x/i + 1) { ///assign是string的一个赋值函数string.assign(const char *, int, int); tmp.assign(str, i*j, i*(x/i+1)); if(x/i+1 > Max) { Max = x/i+1; tmx = tmp; } else { int xn = tmx.size(); if(!xn || tmx > tmp) tmx = tmp; } } int xp = i - x%i; if(xp && j) { for(int k = xp; k < i; k++) { l = rank[i*j-k]; r = rank[i*j+i-k]; if(l > r) swap(l, r); y = querry(l+1, r); int yp = y/i+1; if(yp < Max) continue; tmp.assign(str, i*j-k, i*yp); if(Max < yp) { tmx = tmp; Max = yp; } else { int yn = tmx.size(); if(!yn || tmx > tmp) tmx = tmp; } } } } } printf("Case %d: ",Case); cout<<tmx<<endl;}int main(){ init(); int Case = 1; while(scanf("%s", str) && str[0] != '#') { int n = strlen(str); for(int i = 0; i < n; i++) seq[i] = str[i]-'a'+1; seq[n] = 0; da(seq, sa, n+1, 27); calheight(seq, sa, n); RMQ(n); Del(n, Case++); } return 0;}
- POJ 3693 Maximum repetition substring(后缀数组求最长重复子串)
- POJ - 3693 Maximum repetition substring(后缀数组求重复次数最多的连续重复子串)
- POJ 3693 Maximum repetition substring (后缀数组+RMQ 求重复最多的连续子串)
- POJ 3693 Maximum repetition substring (后缀数组+RMQ 求重复最多的连续子串)
- POJ 3693 Maximum repetition substring 后缀数组求重复次数最多子串
- Maximum repetition substring+POj+后缀数组之求重复次数最多的连续重复子串
- 【POJ】3693 Maximum repetition substring 【后缀数组——求最长连续重复字串】
- POJ 3693 Maximum repetition substring(后缀数组[重复次数最多的连续重复子串])
- poj 3693/hdu 2459 Maximum repetition substring spoj 687. Repeats ( 后缀数组 重复次数最多的连续重复子串)
- POJ 题目 3693 Maximum repetition substring(后缀数组+RMQ+枚举求最小字典序的重复次数最多的子串)
- poj 3693 Maximum repetition substring //后缀数组
- poj 3693 Maximum repetition substring (后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- 【后缀数组】【poj 3693】Maximum repetition substring
- POJ 3693 Maximum Repetition Substring 后缀数组
- poj 1743Maximum repetition substring(后缀数组+RMQ+重复次数最多的连续重复子串))
- POJ 3693 Maximum repetition substring (求重复次数最多的连续子串,4级)
- Swift学习笔记(二)之基本运算符
- WebView Cache 缓存清除
- firefox设置Accept参数和默认字符集
- 第45题 Implement strStr()
- android Parcelable序列化复杂类(该类中含有不是基本类型的集合)
- POJ 3693 Maximum repetition substring(后缀数组求最长重复子串)
- Android Contacts 联系人源码分析
- 【学习笔记】 html学习
- C++ 中的this指针
- activiti designer源码的研究(二)wsdl与bpmn20.xml的对照关系(下)
- 贺岁文:部门正副经理之争
- equals
- Android中View绘制流程以及invalidate()
- log4j.properties配置详解