【HDOJ】2459 Maximum repetition substring

后缀数组+RMQ。

  1 /* 2459 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42
 43 const int INF = 0x3f3f3f3f;
 44 const int maxn = 1e5+5;
 45 char s[maxn];
 46 int a[maxn];
 47 int rrank[maxn], height[maxn], sa[maxn];
 48 int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
 49 int dp[maxn][17];
 50 int mx[maxn], L[maxn];
 51
 52 bool cmp(int *r, int a, int b, int l) {
 53     return r[a]==r[b] && r[a+l]==r[b+l];
 54 }
 55
 56 void da(int *r, int *sa, int n, int m) {
 57     int i, j, *x=wa, *y=wb, *t, p;
 58
 59     for (i=0; i<m; ++i) wc[i] = 0;
 60     for (i=0; i<n; ++i) wc[x[i]=r[i]]++;
 61     for (i=1; i<m; ++i) wc[i] += wc[i-1];
 62     for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i;
 63     for (j=1,p=1; p<n; j*=2, m=p) {
 64         for (p=0,i=n-j; i<n; ++i) y[p++] = i;
 65         for (i=0; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
 66         for (i=0; i<n; ++i) wv[i] = x[y[i]];
 67         for (i=0; i<m; ++i) wc[i] = 0;
 68         for (i=0; i<n; ++i) wc[x[i]]++;
 69         for (i=1; i<m; ++i) wc[i] += wc[i-1];
 70         for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i];
 71         for (t=x, x=y, y=t, p=1, i=1, x[sa[0]]=0; i<n; ++i)
 72             x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++;
 73     }
 74 }
 75
 76 void calheight(int *r, int *sa, int n) {
 77     int i, j, k = 0;
 78
 79     for (i=1; i<=n; ++i) rrank[sa[i]] = i;
 80     for (i=0; i<n; height[rrank[i++]]=k)
 81     for (k?k--:0, j=sa[rrank[i]-1]; r[j+k]==r[i+k]; ++k) ;
 82 }
 83
 84 void init_RMQ(int n) {
 85     int i, j;
 86
 87     for (i=1; i<=n; ++i)
 88         dp[i][0] = height[i];
 89     dp[1][0] = INF;
 90     for (j=1; (1<<j)<=n; ++j)
 91         for (i=1; i+(1<<j)-1<=n; ++i)
 92             dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
 93 }
 94
 95 int RMQ(int l, int r) {
 96     if (l > r)
 97         swap(l, r);
 98
 99     int k = 0;
100     ++l;
101     while (1<<(k+1) <= r-l+1)
102         ++k;
103
104     return min(dp[l][k], dp[r-(1<<k)+1][k]);
105 }
106
107 void printSa(int n) {
108     for (int i=1; i<=n; ++i)
109         printf("%d ", sa[i]);
110     putchar(‘\n‘);
111 }
112
113 void printHeight(int n) {
114     for (int i=1; i<=n; ++i)
115         printf("%d ", height[i]);
116     putchar(‘\n‘);
117 }
118
119 void solve() {
120     int n;
121
122     for (int i=0; ; ++i) {
123         if (s[i] == ‘\0‘) {
124             n = i;
125             break;
126         }
127         a[i] = s[i] - ‘a‘ + 1;
128     }
129     a[n] = 0;
130
131     da(a, sa, n+1, 30);
132     calheight(a, sa, n);
133     init_RMQ(n);
134
135     int n_ = n >> 1, tmp;
136     rep(i, 1, n_) {
137         mx[i] = 0;
138         for (int p=0, q=i; q<n; p=q, q+=i) {
139             tmp = RMQ(rrank[p], rrank[q]);
140             mx[i] = max(mx[i], tmp/i+1);
141             if (tmp%i) {
142                 tmp = RMQ(rrank[p-(i-tmp%i)], rrank[q-(i-tmp%i)]);
143                 mx[i] = max(mx[i], tmp/i+1);
144             }
145         }
146     }
147
148     int ans = 0;
149     rep(i, 1, n_)
150         ans = max(ans, mx[i]);
151
152     int ln = 0;
153     rep(i, 1, n_) {
154         if (mx[i] == ans) {
155             L[ln++] = i;
156         }
157     }
158
159     int beg = 0, len = 0;
160
161     rep(i, 1, n+1) {
162         rep(j, 0, ln) {
163             int p = sa[i];
164             if (p+L[j] >= n)
165                 continue;
166
167             tmp = RMQ(rrank[p], rrank[p+L[j]]);
168             if (tmp/L[j]+1 >= ans) {
169                 beg = p;
170                 len = L[j] * ans;
171                 goto _output;
172             }
173         }
174     }
175
176     _output:
177     s[beg+len] = ‘\0‘;
178     puts(s+beg);
179 }
180
181 int main() {
182     ios::sync_with_stdio(false);
183     #ifndef ONLINE_JUDGE
184         freopen("data.in", "r", stdin);
185         freopen("data.out", "w", stdout);
186     #endif
187
188     int t = 0;
189
190     while (scanf("%s", s)!=EOF && (s[0]!=‘#‘)) {
191         printf("Case %d: ", ++t);
192         solve();
193     }
194
195     #ifndef ONLINE_JUDGE
196         printf("time = %d.\n", (int)clock());
197     #endif
198
199     return 0;
200 }

数据生成器。

 1 from random import randint, shuffle
 2 import shutil
 3 import string
 4
 5
 6 def GenDataIn():
 7     with open("data.in", "w") as fout:
 8         t = 20
 9         bound = 10**2
10         lc = list(string.lowercase)
11         for tt in xrange(t):
12             length = randint(100, 500)
13             line = ""
14             for i in xrange(length):
15                 idx = randint(0, 25)
16                 line += lc[idx]
17             fout.write("%s\n" % line)
18         fout.write("#\n")
19
20
21 def MovDataIn():
22     desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
23     shutil.copyfile("data.in", desFileName)
24
25
26 if __name__ == "__main__":
27     GenDataIn()
28     MovDataIn()
时间: 2024-10-13 01:04:53

【HDOJ】2459 Maximum repetition substring的相关文章

hdu 2459 Maximum repetition substring(后缀数组)

题目链接:hdu 2459 Maximum repetition substring 题意: 让你找一个重复最多的子串,并且输出. 题解: 这个是论文题,看的cxlove的题解,不是很理解为什么这样就能完全找完,当作结论使吧. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 namespace suffixarray{ 5 #define FN(n) f

poj 3693 Maximum repetition substring(后缀数组)

题目链接:poj 3693 Maximum repetition substring 题目大意:求一个字符串中循环子串次数最多的子串. 解题思路:对字符串构建后缀数组,然后枚举循环长度,分区间确定.对于一个长度l,每次求出i和i+l的LCP,那么以i为起点,循环子串长度为l的子串的循环次数为LCP/l+1,然后再考虑一下从i-l+1~i之间有没有存在增长的可能性. #include <cstdio> #include <cstring> #include <vector>

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)