(right集合只包含大于等于v的值 所以val里面存的其实是right集合的最小值)
模板题啊.... 我也不知道为什么UVA那个要开三倍空间才能过 如果有人知道的话求解释啊
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define SF scanf
#define PF printf
#define idx(c) (c-'a')
using namespace std;
typedef long long LL;
const int MAXN = 10000;
int n;
struct SAM {
int ncnt, last;
int fa[MAXN*2+10], ch[MAXN*2+10][26], step[MAXN*2+10];
int val[MAXN*2+10];
SAM () { last = ++ncnt; }
void extend(int c, int v) {
int p = last, np = last = ++ncnt;
step[np] = step[p]+1; val[np] = v;
while(!ch[p][c] && p) ch[p][c] = np, p = fa[p];
if(!p) fa[np] = 1;
else {
int q = ch[p][c], nq;
if(step[p]+1 == step[q]) fa[np] = q;
else {
nq = ++ncnt;
step[nq] = step[p]+1; val[nq] = val[q];
memcpy(ch[nq], ch[q], sizeof(ch[p]));
fa[nq] = fa[q];
fa[np] = fa[q] = nq;
while(ch[p][c] == q) ch[p][c] = nq, p = fa[p];
}
}
}
void init() {
last = ncnt = 1;
memset(ch[1], 0, sizeof(ch));
}
void build(char *s) {
init();
int len = strlen(s);
for(int i = 0; i < len; i++)
extend(idx(s[i]), i+1);
}
} sam;
char s[MAXN*2+10];
int main() {
int _T; SF("%d", &_T); while(_T--) {
SF("%s", s);
n = strlen(s);
for(int i = 0; i < n; i++) s[i+n] = s[i];
s[n<<1] = 0;
sam.build(s);
int cur = 1;
for(int i = 0; i < n; i++)
for(int j = 0; j < 26; j++)
if(sam.ch[cur][j]) {
cur = sam.ch[cur][j];
break;
}
PF("%d\n", sam.val[cur]-n+1);
}
}