POJ 3693 Maximum repetition substring(字尾陣列求最長重複子串)
題目大意:和spoj687類似,就是當長度相同是需要輸出一個最小的字典序的序列。
解體思路:這次需要列舉所有的從i到d = i-L/i (d = i-L%i)的位置,然後記錄保證最大值的同時,求出來字典序最小的。
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7418 | Accepted: 2217 |
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
ccabababc daabbccaa #
Sample Output
Case 1: ababab Case 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;
}
相關文章
- 求字串中不含重複字元的最長子串字串字元
- LeetCode3:Longest Substring Without Repeating Characters(無重複字元的最長子串)LeetCode字元
- 無重複字元的最長子串字元
- 【Leetcode】3. Longest Substring Without RepeatingCharacters無重最長子串LeetCodeGC
- 3 無重複字元的最長子串字元
- LeetCode——無重複字元的最長子串LeetCode字元
- java無重複字元的最長子串Java字元
- 字尾陣列複習陣列
- leetcode 之無重複字元的最長子串LeetCode字元
- 【LeetCode】3 無重複字元的最長子串LeetCode字元
- 3. 無重複字元的最長子串字元
- 演算法練習:求字串的最長重複子串(Java實現)演算法字串Java
- 演算法-無重複字元的最長子串演算法字元
- LeetCode-3. 無重複字元的最長子串LeetCode字元
- Leetcode 3. 無重複字元的最長子串LeetCode字元
- 【每日一題】無重複字元的最長子串每日一題字元
- leetcode-3無重複字元的最長子串LeetCode字元
- 【leetcode】【java】【3、無重複字元的最長子串】LeetCodeJava字元
- 最長公共子串 二維陣列 Go實現陣列Go
- Leetcode5: Longest Palindromic Substring(最長迴文子串)LeetCode
- LCR 016. 無重複字元的最長子串(中)字元
- LeetCode題集-3 - 無重複字元的最長子串LeetCode字元
- 每日leetcode——3. 無重複字元的最長子串LeetCode字元
- POJ1743 Musical Theme(字尾陣列 二分)陣列
- LeetCode133:給定一個字串,找出最長的不具有重複字元的子串的長度。例如,“abcabcbb”不具有重複字元的最長子串是“abc”,長度為3。對於“bbbbb”,最長的不具有重複字元的子串是LeetCode字串字元
- 【LeetCode動態規劃#14】子序列系列題(最長遞增子序列、最長連續遞增序列、最長重複子陣列、最長公共子序列)LeetCode動態規劃陣列
- 最長子串
- #leetcode刷題之路3-無重複字元的最長子串LeetCode字元
- [LeetCode 刷題] 3. 無重複字元的最長子串 (Medium)LeetCode字元
- 978 最長湍流子陣列陣列
- LeetCode(1297):子串的最大出現次數 Maximum Number of Occurrences of a Substring(Java)LeetCodeJava
- Day 45 | 300.最長遞增子序列 、674. 最長連續遞增序列 、718. 最長重複子陣列陣列
- 最長上升子串
- DreamJudge-1294-字尾子串排序排序
- 字尾陣列 SA陣列
- 字尾陣列模板陣列
- 字尾陣列,SA陣列
- 陣列中重複的數字陣列
- 用滑動視窗來解決最長無重複子串問題