/***********************************************************************************
用Gvim写的, 解法就是求出后缀数组后,算h值最大,并且在'#'两侧的两个串
***********************************************************************************/
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define L(x) ((x) << 1)
#define R(x) ((x) << 1 | 1)
//#define ONLINE_JUDGE
typedef double LF;
const LF eps = 10e-6;
const int MAXN = 2000005; //the max length of string
const int MAXC = 128; //the max value of a character
char ss[MAXN], ch[MAXN];
int wa[MAXN], wb[MAXN], wv[MAXN], wc[MAXC], dp[MAXN][22]; //!!!notice wc
int rk[MAXN],h[MAXN], r[MAXN * 3], sa[MAXN * 3];
int inc[22];
int c0(int *r, int a, int b)
{
return r[a] == r[b] &&
r[a + 1] == r[b + 1] &&
r[a + 2] == r[b + 2];
}
int c12(int k, int *r, int a, int b)
{
if(2 == k)
{
return r[a] < r[b] || r[a] == r[b] && c12(1,r,a + 1,b + 1);
}
else
{
return r[a] < r[b] || r[a] == r[b] && wv[a + 1] < wv[b + 1];
}
}
inline int F(int x, int tb)
{
return x / 3 + (1 == x % 3 ? 0 : tb);
}
inline int G(int x, int tb)
{
return x < tb ? x * 3 + 1 : (x - tb) * 3 + 2;
}
void sort(int *r, int *a, int *b, int n, int m)
{
int i;
for(i = 0; i < n; i++)
{
wv[i] = r[ a[i] ];
}
for(i = 0; i < m; i++)
{
wc[i] = 0;
}
for(i = 0; i < n; i++)
{
wc[ wv[i] ]++;
}
for(i = 1; i < m; i++)
{
wc[i] += wc[i - 1];
}
for(i = n - 1; i >= 0; i--)
{
b[ --wc[ wv[i] ] ] = a[i];
}
return;
}
void dc3(int *r, int *sa, int n, int m)
{
int i, j, *rn = r + n, *san = sa + n, ta = 0, tb = (n + 1) / 3, tbc = 0, p;
r[n] = r[n + 1] = 0;
for(i = 0; i < n; i++)
{
if(i % 3 != 0)
{
wa[tbc++] = i;
}
}
sort(r + 2, wa, wb, tbc, m);
sort(r + 1, wb, wa, tbc, m);
sort(r, wa, wb, tbc, m);
for(p = 1,rn[ F(wb[0], tb) ] = 0, i = 1; i < tbc; i++)
{
rn[ F(wb[i], tb) ] = c0(r, wb[i - 1], wb[i]) ? p - 1: p++;
}
if( p < tbc)
{
dc3(rn, san, tbc, p);
}
else
{
for(i = 0; i < tbc; i++)
{
san[ rn[i] ] = i;
}
}
for(i = 0; i < tbc; i++)
{
if(san[i] < tb)
{
wb[ta++] = san[i] * 3;
}
}
if(1 == n % 3)
{
wb[ta++] = n - 1;
}
sort(r, wb, wa, ta, m);
for(i = 0; i < tbc; i++)
{
wv[ wb[i] = G(san[i], tb) ] = i;
}
for(i = 0, j = 0, p = 0; i < ta && j < tbc; p++)
{
sa[p] = c12(wb[j] % 3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
}
for( ; i < ta; p++)
{
sa[p] = wa[i++];
}
for( ; j < tbc; p++)
{
sa[p] = wb[j++];
}
return;
}
void calheight(int *r, int *sa, int n)
{
for(int i = 0; i < n; ++i)
{
rk[ sa[i] ] = i;
}
for(int i = 0, k = 0; i < n; ++i)
{
if(rk[i] == n - 1)
{
h[ rk[i] ] = k = 0;
}
else
{
if(k > 0)
{
--k;
}
int j = sa[ rk[i] + 1 ];
while(r[i + k] == r[j + k])
{
++k;
}
h[ rk[i] ] = k;
}
}
return ;
}
void test(int n)
{
for(int i = 0; i < n; ++i)
{
printf("%d %d %d %d\n", i, sa[i], rk[i], h[i]);
}
return ;
}
void preprocess()
{
inc[0] = 1;
for(int i = 1; i < 22; ++i)
{
inc[i] = inc[i - 1] << 1;
}
return ;
}
void initRMQ(int ind)
{
int cap = static_cast<int>( log(ind + 0.0) / log(2.0) ), mid;
for(int i = 0; i < ind; ++i)
{
dp[i][0] = h[i];
}
for(int j = 1; j <= cap; ++j)
{
for(int i = 0; i + inc[j] - 1 < ind; ++i)
{
mid = i + inc[j - 1];
dp[i][j] = min(dp[i][j - 1], dp[mid][j - 1]);
}
}
return ;
}
int query(int x, int y) //query the minimum number between the range of h[x, y];
{
int k = static_cast<int>( log(y - x + 1.0) / log(2.0) );
return min(dp[x][k], dp[y - inc[k] + 1][k]);
}
void ace()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int n, m;
int maxi;
while (gets(ss))
{
gets(ch);
m = strlen(ss);
ss[m++] = '#';
ss[m++] = '\0';
strcat(ss, ch);
n = strlen(ss);
ss[n++] = '\0';
for (int i = 0; i < n; ++i)
{
r[i] = ss[i];
}
dc3(r, sa, n, MAXC);
calheight(r, sa, n);
maxi = 0;
for (int i = 0; i < n - 1; ++i)
{
if (h[i] > maxi)
{
if (sa[i] < m && sa[i + 1] > m || sa[i + 1] < m && sa[i] > m)
{
maxi = h[i];
}
}
}
printf("%d\n", maxi);
}
return ;
}
int main()
{
preprocess();
ace();
return 0;
}
HDU 1403 Suffix Array
最新推荐文章于 2022-04-15 21:41:32 发布