import
java.util.*;
class
Suffix
implements
Comparable<Suffix> {
int
index;
int
[] rank =
new
int
[
2
];
public
int
compareTo(Suffix s)
{
if
(rank[
0
] == s.rank[
0
]) {
return
Integer.compare(rank[
1
], s.rank[
1
]);
}
else
{
return
Integer.compare(rank[
0
], s.rank[
0
]);
}
}
}
class
Main {
static
int
[] buildSuffixArray(String txt,
int
n)
{
Suffix[] suffixes =
new
Suffix[n];
for
(
int
i =
0
; i < n; i++) {
suffixes[i] =
new
Suffix();
suffixes[i].index = i;
suffixes[i].rank[
0
] = txt.charAt(i) -
'a'
;
suffixes[i].rank[
1
]
= (i +
1
) < n ? txt.charAt(i +
1
) -
'a'
: -
1
;
}
Arrays.sort(suffixes);
int
[] ind =
new
int
[n];
for
(
int
k =
4
; k <
2
* n; k = k *
2
) {
int
rank =
0
;
int
prevRank = suffixes[
0
].rank[
0
];
suffixes[
0
].rank[
0
] = rank;
ind[suffixes[
0
].index] =
0
;
for
(
int
i =
1
; i < n; i++) {
if
(suffixes[i].rank[
0
] == prevRank
&& suffixes[i].rank[
1
]
== suffixes[i -
1
].rank[
1
]) {
prevRank = suffixes[i].rank[
0
];
suffixes[i].rank[
0
] = rank;
}
else
{
prevRank = suffixes[i].rank[
0
];
suffixes[i].rank[
0
] = ++rank;
}
ind[suffixes[i].index] = i;
}
for
(
int
i =
0
; i < n; i++) {
int
nextIndex = suffixes[i].index + k /
2
;
suffixes[i].rank[
1
]
= nextIndex < n
? suffixes[ind[nextIndex]].rank[
0
]
: -
1
;
}
Arrays.sort(suffixes);
}
int
[] suffixArr =
new
int
[n];
for
(
int
i =
0
; i < n; i++) {
suffixArr[i] = suffixes[i].index;
}
return
suffixArr;
}
static
int
[] Const_LCP(String txt,
int
[] suffixArr)
{
int
n = suffixArr.length;
int
[] lcp =
new
int
[n];
int
[] invSuff =
new
int
[n];
for
(
int
i =
0
; i < n; i++) {
invSuff[suffixArr[i]] = i;
}
int
k =
0
;
for
(
int
i =
0
; i < n; i++) {
if
(invSuff[i] == n -
1
) {
k =
0
;
continue
;
}
int
j = suffixArr[invSuff[i] +
1
];
while
(i + k < n && j + k < n
&& txt.charAt(i + k)
== txt.charAt(j + k)) {
k++;
}
lcp[invSuff[i]] = k;
if
(k >
0
) {
k--;
}
}
return
lcp;
}
static
int
cnt_Dist_Substr(String txt)
{
int
n = txt.length();
int
[] suffixArr = buildSuffixArray(txt, n);
int
[] lcp = Const_LCP(txt, suffixArr);
int
result = n - suffixArr[
0
];
for
(
int
i =
1
; i < lcp.length; i++) {
result += (n - suffixArr[i]) - lcp[i -
1
];
}
result++;
return
result;
}
public
static
void
main(String[] args)
{
String txt =
"ababa"
;
System.out.println(cnt_Dist_Substr(txt));
}
}