void
work
(
int
*s
,
int n
,
int m
)
{
int
*x
= t
;
int
*y
= t2
;
for
(
int i
=
1
; i
<= m
; i
++) c
[i
]
=
0
;
for
(
int i
=
1
; i
<= n
; i
++) c
[x
[i
]
= s
[i
]]++;
for
(
int i
=
1
; i
<= m
; i
++) c
[i
]
+= c
[i
-
1
];
for
(
int i
= n
; i
>=
1
; i
--) sa
[c
[x
[i
]]--]
= i
;
for
(
int k
=
1
; k
<= n
; k
<<=
1
)
{
int p
=
0
;
for
(
int i
= n
- k
+
1
; i
<= n
; i
++) y
[++p
]
= i
;
for
(
int i
=
1
; i
<= n
; i
++)
if
(sa
[i
]
> k
) y
[++p
]
= sa
[i
]
- k
;
for
(
int i
=
1
; i
<= m
; i
++) c
[i
]
=
0
;
for
(
int i
=
1
; i
<= n
; i
++) c
[x
[y
[i
]]]++;
for
(
int i
=
1
; i
<= m
; i
++) c
[i
]
+= c
[i
-
1
];
for
(
int i
= n
; i
>=
1
; i
--) sa
[c
[x
[y
[i
]]]--]
= y
[i
];
std::swap
(
x
,
y
);
p
=
1
;
x
[sa
[
1
]]
=
1
;
for
(
int i
=
2
; i
<= n
; i
++)
{
x
[sa
[i
]]
= y
[sa
[i
]]
== y
[sa
[i
-
1
]]
&& y
[sa
[i
]
+ k
]
== y
[sa
[i
-
1
]
+ k
]
? p
:
++p
;
}
if
(p
>= n
)
break
;
m
= p
;
}
}
void
cal_array
(
int
*s
,
int n
)
{
int k
=
0
;
for
(
int i
=
1
; i
<= n
; i
++) rk
[sa
[i
]]
= i
;
for
(
int i
=
1
; i
<= n
; i
++)
{
if
(k
) k
--;
int j
= sa
[rk
[i
]
-
1
];
while
(s
[i
+ k
]
== s
[j
+ k
]) k
++;
h
[rk
[i
]]
= k
;
}
}