#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define pb push_back
#define fi first
#define se second
#define ld double
const int md = 1e9+7;
const int K = 26;
struct node{
int next[K],go[K],link = -1,e_link = -1;
bool leaf = 0;
char pch;
int p = -1;
int id;
node(int p = -1,char ch = '#'):p(p),pch(ch){
fill(next,next+K,-1);
fill(go,go+K,-1);
}
};
vector<node> t(1);
void add_string(string s,int id){
int c = 0;
for(char ch: s){
int v = ch-'a';
if(t[c].next[v]==-1){
t[c].next[v] = t.size();
t.emplace_back(c,ch);
}
c = t[c].next[v];
}
t[c].leaf = 1;
t[c].id = id;
}
int go(int c,char ch);
int get_link(int c){
if(t[c].link==-1){
if(c==0 || t[c].p==0)
t[c].link = 0;
else
t[c].link = go(get_link(t[c].p),t[c].pch);
get_link(t[c].link);
if(t[t[c].link].leaf)
t[c].e_link = t[c].link;
else
t[c].e_link = t[t[c].link].e_link;
}
return t[c].link;
}
int go(int c,char ch){
int v = ch-'a';
if(t[c].go[v]==-1){
if(t[c].next[v]!=-1)
t[c].go[v] = t[c].next[v];
else
t[c].go[v] = (c==0)? 0: go(get_link(c),ch);
}
return t[c].go[v];
}
void search(char s[]){
int n = strlen(s);
int c = 0;
for(int i=0;i<n;i++){
c = go(c,s[i]);
int cc = c;
while(cc!=-1){
if(t[c].leaf)
cout<<i<<" "<<t[cc].id<<endl; // end position and string id
cc = t[cc].e_link;
}
}
}
signed main()
{
string arr[3] = {"a", "aa", "aaa"};
for(int i=0;i<3;i++)
add_string(arr[i],i);
for(int i = 1; i < t.size(); i++) //
get_link(i); //
char s[] = "aaaaa";
search(s);
return 0;
}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdHlwZWRlZiBsb25nIGxvbmcgaW50IGxsOwojZGVmaW5lIHBiIHB1c2hfYmFjawojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2Ugc2Vjb25kCiNkZWZpbmUgbGQgZG91YmxlCmNvbnN0IGludCBtZCA9IDFlOSs3OwoKY29uc3QgaW50IEsgPSAyNjsKc3RydWN0IG5vZGV7CiAgICBpbnQgbmV4dFtLXSxnb1tLXSxsaW5rID0gLTEsZV9saW5rID0gLTE7CiAgICBib29sIGxlYWYgPSAwOwogICAgY2hhciBwY2g7CiAgICBpbnQgcCA9IC0xOwogICAgaW50IGlkOwogICAgbm9kZShpbnQgcCA9IC0xLGNoYXIgY2ggPSAnIycpOnAocCkscGNoKGNoKXsKICAgICAgICBmaWxsKG5leHQsbmV4dCtLLC0xKTsKICAgICAgICBmaWxsKGdvLGdvK0ssLTEpOwogICAgfQp9Owp2ZWN0b3I8bm9kZT4gdCgxKTsKdm9pZCBhZGRfc3RyaW5nKHN0cmluZyBzLGludCBpZCl7CiAgICBpbnQgYyA9IDA7CiAgICBmb3IoY2hhciBjaDogcyl7CiAgICAgICAgaW50IHYgPSBjaC0nYSc7CiAgICAgICAgaWYodFtjXS5uZXh0W3ZdPT0tMSl7CiAgICAgICAgICAgIHRbY10ubmV4dFt2XSA9IHQuc2l6ZSgpOwogICAgICAgICAgICB0LmVtcGxhY2VfYmFjayhjLGNoKTsKICAgICAgICB9CiAgICAgICAgYyA9IHRbY10ubmV4dFt2XTsKICAgIH0KICAgIHRbY10ubGVhZiA9IDE7CiAgICB0W2NdLmlkID0gaWQ7Cn0KaW50IGdvKGludCBjLGNoYXIgY2gpOwppbnQgZ2V0X2xpbmsoaW50IGMpewogICAgaWYodFtjXS5saW5rPT0tMSl7CiAgICAgICAgaWYoYz09MCB8fCB0W2NdLnA9PTApCiAgICAgICAgICAgIHRbY10ubGluayA9IDA7CiAgICAgICAgZWxzZQogICAgICAgICAgICB0W2NdLmxpbmsgPSBnbyhnZXRfbGluayh0W2NdLnApLHRbY10ucGNoKTsKICAgICAgICBnZXRfbGluayh0W2NdLmxpbmspOwogICAgICAgIGlmKHRbdFtjXS5saW5rXS5sZWFmKQogICAgICAgICAgICB0W2NdLmVfbGluayA9IHRbY10ubGluazsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRbY10uZV9saW5rID0gdFt0W2NdLmxpbmtdLmVfbGluazsKICAgIH0KICAgIHJldHVybiB0W2NdLmxpbms7Cn0KaW50IGdvKGludCBjLGNoYXIgY2gpewogICAgaW50IHYgPSBjaC0nYSc7CiAgICBpZih0W2NdLmdvW3ZdPT0tMSl7CiAgICAgICAgaWYodFtjXS5uZXh0W3ZdIT0tMSkKICAgICAgICAgICAgdFtjXS5nb1t2XSA9IHRbY10ubmV4dFt2XTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRbY10uZ29bdl0gPSAoYz09MCk/IDA6IGdvKGdldF9saW5rKGMpLGNoKTsKICAgIH0KICAgIHJldHVybiB0W2NdLmdvW3ZdOwp9CnZvaWQgc2VhcmNoKGNoYXIgc1tdKXsKICAgIGludCBuID0gc3RybGVuKHMpOwogICAgaW50IGMgPSAwOwogICAgZm9yKGludCBpPTA7aTxuO2krKyl7CiAgICAgICAgYyA9IGdvKGMsc1tpXSk7CiAgICAgICAgaW50IGNjID0gYzsKICAgICAgICB3aGlsZShjYyE9LTEpewogICAgICAgICAgICBpZih0W2NdLmxlYWYpCiAgICAgICAgICAgIGNvdXQ8PGk8PCIgIjw8dFtjY10uaWQ8PGVuZGw7IC8vIGVuZCBwb3NpdGlvbiBhbmQgc3RyaW5nIGlkCiAgICAgICAgICAgIGNjID0gdFtjY10uZV9saW5rOwogICAgICAgIH0KICAgIH0KfQpzaWduZWQgbWFpbigpCnsKICAgIHN0cmluZyBhcnJbM10gPSB7ImEiLCAiYWEiLCAiYWFhIn07CiAgICBmb3IoaW50IGk9MDtpPDM7aSsrKQogICAgICAgIGFkZF9zdHJpbmcoYXJyW2ldLGkpOwogICAgZm9yKGludCBpID0gMTsgaSA8IHQuc2l6ZSgpOyBpKyspIC8vIAogICAgICAgIGdldF9saW5rKGkpOyAvLyAKICAgIGNoYXIgc1tdID0gImFhYWFhIjsKICAgIHNlYXJjaChzKTsKICAgIHJldHVybiAwOwp9