题意:求一个字符串的最小表示的开始下标
就当模板题写了
把字符串重复一遍,再建后缀自动机,贪心的选最小字典序在上面走len步
因为走出来的一定是子串,长度又是len,所以一定是原来的字符串旋转得到的,就解决了
const
maxn=;
type
node=record
go:array[..]of longint;
step,fa:longint;
end; var
sam:array[..maxn]of node;
s,ans:ansistring;
len,tot,last,t:longint; procedure add(x:longint);
var
now,new,q:longint;
begin
inc(tot);
now:=tot;
fillchar(sam[now].go,sizeof(sam[now].go),);
sam[now].step:=sam[last].step+;
while (last<>)and(sam[last].go[x]=) do
begin
sam[last].go[x]:=now;
last:=sam[last].fa;
end;
if last= then sam[now].fa:=
else
begin
q:=sam[last].go[x];
if sam[q].step=sam[last].step+ then sam[now].fa:=q
else
begin
inc(tot);
new:=tot;
sam[new]:=sam[q];
sam[q].fa:=new;
sam[now].fa:=new;
sam[new].step:=sam[last].step+;
while (last<>)and(sam[last].go[x]=q) do
begin
sam[last].go[x]:=new;
last:=sam[last].fa;
end;
end;
end;
last:=now;
end; procedure main;
var
i,j,k:longint;
begin
readln(s);
s:=s+s;
len:=length(s);
last:=;
tot:=;
sam[].fa:=;
sam[].step:=;
fillchar(sam[].go,sizeof(sam[].go),);
for i:= to len do
add(ord(s[i])-ord('a'));
i:=;
j:=;
ans:='';
while j<len>> do
begin
inc(j);
for k:= to do
if sam[i].go[k]<> then break;
ans:=ans+chr(k+ord('a'));
i:=sam[i].go[k];
end;
writeln(pos(ans,s));
end; begin
readln(t);
while t<> do
begin
main;
dec(t);
end;
end.