比赛 |
NOIP模拟赛by mzx Day2 |
评测结果 |
WWWWWWWTTT |
题目名称 |
拯救紫萱学姐 |
最终得分 |
0 |
用户昵称 |
sxysxy |
运行时间 |
5.131 s |
代码语言 |
C++ |
内存使用 |
230.15 MiB |
提交时间 |
2016-10-20 21:07:08 |
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <iostream>
#include <queue>
#include <string>
#include <cstring>
#include <vector>
#include <cctype>
using namespace std;
#define MAXN 1000001
class SAM
{
int last, size;
public:
struct state
{
int link;
int len;
int next[26];
void init()
{
len = 0;
link = -1;
memset(next, 0, sizeof(next));
}
}st[MAXN<<1];
int rec[MAXN<<1];
SAM()
{
last = size = 0;
newst();
}
int newst()
{
st[size++].init();
return size-1;
}
int expand(int c)
{
int cur = newst();
st[cur].len = st[last].len+1;
int p;
for(p = last; ~p && !st[p].next[c]; p = st[p].link)
st[p].next[c] = cur;
if(p == -1)
st[cur].link = 0;
else
{
int q = st[p].next[c];
if(st[q].len == st[p].len+1)
st[cur].link = q;
else
{
int clone = newst();
memcpy(st[clone].next, st[q].next, sizeof(st[q].next));
st[clone].len = st[p].len+1;
st[clone].link = st[q].link;
for(; ~p && st[p].next[c] == q; p = st[p].link)
st[p].next[c] = clone;
st[q].link = st[cur].link = clone;
}
}
return last = cur;
}
}sam;
int read_string(char *s)
{
int len = 1;
char c;
while(!isalpha(c = getchar()));
s[0] = c;
while(isalpha(c = getchar()))s[len++] = c;
s[len] = 0;
return len;
}
typedef long long LL;
char str[MAXN];
LL comm[MAXN];
int main()
{
freopen("savemzx.in", "r", stdin);
freopen("savemzx.out", "w", stdout);
int len = read_string(str);
int s = 0; //前缀状态指针
int match = 0;
for(int i = 1; i <= len; i++)
{
comm[i] = 0; //最开始认为没有公共部分
int c = str[i-1]-'a';
int t = sam.expand(c); //加入字符构成的状态节点
if(sam.st[t].link || i == 1) //之前出现过这个字符/开头字符
{
while(~t && sam.st[t].len != sam.st[s].len+1)
t = sam.st[t].link;
if(~t)
{
s = sam.st[s].next[c];
match = sam.st[t].len;
}
}else
{
s = 0;
match = 0;
}
comm[i] = match;
}
LL ans = 0;
for(int i = 1; i <= len; i++)
{
for(int j = i+1; j <= len; j++)
{
LL cnt = 0;
int a = i;
int b = j;
while(a)
{
cnt += (a-comm[a])*(a-comm[a]);
if(a == comm[a])
{
cnt += a*a;
break;
}
a = comm[a];
}
while(b)
{
cnt += (b-comm[b])*(b-comm[b]);
if(b == comm[b])
{
cnt += b*b;
break;
}
b = comm[b];
}
ans = max(ans, cnt);
}
}
printf("%lld\n", ans);
return 0;
}