[BZOJ 3654] 图样图森破

789人阅读 评论(0)

Solution ：

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <bitset>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <iterator>
#include <vector>
#include <queue>
#include <set>
#include <map>

#define rep(i, x, y) for (int i = (x), _ = (y); i <= _; ++i)
#define down(i, x, y) for (int i = (x), _ = (y); i >= _; --i)
#define x first
#define y second
#define LX_JUDGE

using namespace std;
typedef long long LL;

template<typename T> inline void upMax(T & x, T y) { x < y ? x = y : 0; }
template<typename T> inline void upMin(T & x, T y) { x > y ? x = y : 0; }

template<typename T>
{
char c;
while ((c = getchar()) < '0' || c > '9') ;
for (x = c - '0'; (c = getchar()) >= '0' && c <= '9'; x = x * 10 + c - '0') ;
}

const LL inf = 1e15;
const int N = 2e5 + 3e4;

namespace suffixArray
{
int Sa[N], Rank[N], height[N];
int mn[N][19], Log[N], tot;

void suffixDa(char * r, int n, int m)
{
static int ws[N];
int i, j, p, *x = Rank, *y = height;
tot = n;

memset(ws, 0, sizeof(int) * m);
for (i = 0; i < n; ++i)
++ws[x[i] = r[i]];
for (i = 1; i < m; ++i)
ws[i] += ws[i - 1];
for (i = n - 1; ~i; --i)
Sa[--ws[x[i]]] = i;
for (j = 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;
memset(ws, 0, sizeof(int) * m);
for (i = 0; i < n; ++i)
++ws[x[i]];
for (i = 1; i < m; ++i)
ws[i] += ws[i - 1];
for (i = n - 1; ~i; --i)
Sa[--ws[x[y[i]]]] = y[i];
swap(x, y);
x[Sa[0]] = 0, p = 1;
for (i = 1; i < n; ++i)
x[Sa[i]] = (y[Sa[i - 1]] == y[Sa[i]] && y[Sa[i - 1] + j] == y[Sa[i] + j]) ? p - 1 : p++;
}
for (i = 0; i < n; ++i)
Rank[Sa[i]] = i;
for (i = p = 0; i < n - 1; ++i)
{
p ? --p : 0;
j = Sa[Rank[i] - 1];
while (r[i + p] == r[j + p])
++p;
height[Rank[i]] = p;
}
height[0] = height[1] = height[n] = 0;

rep (i, 2, n)
Log[i] = Log[i >> 1] + 1;

rep (i, 0, n - 1)
mn[i][0] = height[i];

rep (i, 0, Log[n] - 1)
{
rep (j, 0, n - (1 << (i + 1)) + 1)
mn[j][i + 1] = min(mn[j][i], mn[j + (1 << i)][i]);
}
}

int Lcp(int x, int y)
{
if (x == y)
x = Rank[x], y = Rank[y];
if (x > y)
swap(x, y);
int k = Log[y - x];
return min(mn[x + 1][k], mn[y - (1 << k) + 1][k]);
}
}

char str[N];
int belong[N], start[211], last[211];
int n, m;

LL f[N];
bool ins[N];

LL calc(int x)
{
using suffixArray::Lcp;

if (str[x] < 'a')
x = m;

if (ins[x])
return inf;
else if (f[x] > 0)
return f[x];

LL &ans = f[x];
ins[x] = 1;

if (x == m)
{
rep (i, 1, n + n)
upMax(ans, calc(start[i]));
}
else
{
int p = belong[x];

rep (j, (p <= n ? n + 1 : 1), (p <= n ? n + n : n))
{
int t = min(Lcp(x, start[j]), min(last[p] - x, last[j] - start[j]));
if (x + t == last[p])
upMax(ans, calc(start[j] + t) + t * 2);
else if (start[j] + t == last[j])
upMax(ans, calc(x + t) + t * 2);
else
upMax(ans, 2ll * t);
}
}

upMax(ans, 0ll), upMin(ans, inf);
ins[x] = 0;

return ans;
}

int main()
{
#ifdef LX_JUDGE
freopen("in.txt", "r", stdin);
#endif

rep (i, 1, n)
{
scanf("%s", str + m);
start[i] = m;
while (str[m])
belong[m++] = i;
last[i] = m;
str[m++] = 'a' - 1;
}

int cur = 0;

rep (i, n + 1, n + n)
{
start[i] = m;
while (str[cur] >= 'a')
{
belong[m] = i;
str[m++] = str[cur++];
}
last[i] = m;
str[m++] = str[cur++];
reverse(str + start[i], str + last[i]);
}

str[m++] = 0;
suffixArray::suffixDa(str, m, 128);

memset(f, -1, sizeof(f));

LL ans = calc(m);

rep (i, 1, n)
{
using suffixArray::Lcp;
for (int j = start[i], k = last[i + n] - 1; j < last[i]; ++j, --k)
{
int tmp = min(Lcp(j, k), min(last[i] - j, last[i + n] - k));

if (j + tmp == last[i])
upMax(ans, calc(k + tmp) + 2 * tmp - 1);
else if (k + tmp == last[i + n])
upMax(ans, calc(j + tmp) + 2 * tmp - 1);
else
upMax(ans, 2ll * tmp - 1);
}
for (int j = start[i] + 1, k = last[i + n] - 1; j < last[i]; ++j, --k)
{
int tmp = min(Lcp(j, k), min(last[i] - j, last[i + n] - k));

if (j + tmp == last[i])
upMax(ans, calc(k + tmp) + tmp * 2);
else if (k + tmp == last[i + n])
upMax(ans, calc(j + tmp) + tmp * 2);
else
upMax(ans, 2ll * tmp);
}
}

ans < inf ? printf("%lld\n", ans) : puts("Infinity");

return 0;
}
0
0

个人资料
• 访问：39081次
• 积分：700
• 等级：
• 排名：千里之外
• 原创：29篇
• 转载：0篇
• 译文：1篇
• 评论：13条
文章分类
最新评论