把所有的字符串都存进去,然后再求出不同的子串个数即可。
// Created by CAD
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e6+5;
struct state{
int len,link;
vector<int> Next;
state(){Next.resize(10);}
}st[maxn];
int siz=0,last=0;
void init(){
st[0].len=0;
st[0].link=-1;
}
void extend(int c){
int cur=++siz;
st[cur].len=st[last].len+1;
int p=last;
while(~p&&!st[p].Next[c]){
st[p].Next[c]=cur;
p=st[p].link;
}
if(p==-1) st[cur].link=0;
else{
int q=st[p].Next[c];
if(st[p].len+1==st[q].len) st[cur].link=q;
else{
int clone=++siz;
st[clone].len=st[p].len+1;
st[clone].Next=st[q].Next;
st[clone].link=st[q].link;
while(~p && st[p].Next[c]==q){
st[p].Next[c]=clone;
p=st[p].link;
}
st[q].link=st[cur].link=clone;
}
}
last=cur;
}
int pos[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
string s;cin>>s;s=" "+s;
init();
int n=s.length()-1;
pos[n+1]=0;
stack<int> stk;
for(int i=n;i>=1;--i){
while(!stk.empty()&&s[stk.top()]<s[i]) stk.pop();
int k=stk.empty()?n+1:stk.top();
last=pos[k];
for(int j=i;j<k;++j) extend(s[i]-'a');
pos[i]=last;
stk.push(i);
}
ll ans=0;
for(int i=1;i<=siz;++i) ans+=st[i].len-st[st[i].link].len;
cout<<ans<<endl;
return 0;
}