#include using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define trav(a, x) for(auto& a : x) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() typedef long long ll; typedef pair pii; typedef pair pll; typedef vector vi; typedef vector vl; typedef long double ld; struct SuffixArray { vi sa, lcp; SuffixArray(string& s, int lim=256) { // or basic_string int n = sz(s) + 1, k = 0, a, b; vi x(all(s)), y(n), ws(max(n, lim)), rank(n); x.push_back(0), sa = lcp = y, iota(all(sa), 0); for (int j = 0, p = 0; p < n; j = max(1, j * 2), lim = p) { p = j, iota(all(y), n - j); rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i] - j; fill(all(ws), 0); rep(i,0,n) ws[x[i]]++; rep(i,1,lim) ws[i] += ws[i - 1]; for (int i = n; i--;) sa[--ws[x[y[i]]]] = y[i]; swap(x, y), p = 1, x[sa[0]] = 0; rep(i,1,n) a = sa[i - 1], b = sa[i], x[b] = (y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++; } rep(i,1,n) rank[sa[i]] = i; for (int i = 0, j; i < n - 1; lcp[rank[i++]] = k) for (k && k--, j = sa[rank[i] - 1]; s[i + k] == s[j + k]; k++); } }; int n; const int MAXN = 1000003; string s; ll NUM[10] = {0}; ll CH[52] = {0}; ll CH2[52] = {0}; void upd_num(ll x, ll f){ while(x > 0){ NUM[x%10]+=f; x /= 10; } } int ch_to_int(char ch){ if(ch <= 'Z')return ch-'A'; return ch-'a'+26; } string alfa = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> s; n = sz(s); SuffixArray SA(s); // Letters vl CS1(n+1, 0); vl CS2(n+1, 0); rep(c1,0,n){ int c = SA.lcp[c1+1]+1; int i = SA.sa[c1+1]; int suff = n-i-c; CS1[i] += suff+1; CS1[i+c] -= suff+1; CS2[i+c]++; } rep(c1,0,n){ CH[ch_to_int(s[c1])] += CS1[c1]; CS1[c1+1] += CS1[c1]; } for(int c1 = n-1; c1 >= 0; c1--){ ll x = n-c1; CH2[ch_to_int(s[c1])] += x; rep(c2,0,52){ CH[c2] += CS2[c1]*CH2[c2]; } } // Numbers vector st; rep(c1,0,n){ ll L = SA.lcp[c1+1]; ll i = SA.sa[c1+1]; ll tot = n-SA.sa[c1]; ll x = 0; while(sz(st) > 0 && tot-st.back().first >= L){ upd_num(x+st.back().second, st.back().first); tot -= st.back().first; x += st.back().second; st.pop_back(); } if(tot > L){ upd_num(x+st.back().second, tot-L); st[sz(st)-1].first -= tot-L; tot = L; if(st.back().first == 0){ x += st.back().second; st.pop_back(); } } if(sz(st) > 0){ st[sz(st)-1].second += x; } if(n-i > L){ st.push_back({n-i-L, 1}); } } if(sz(st) > 0){ ll x = 0; while(sz(st) > 0){ upd_num(x+st.back().second, st.back().first); x += st.back().second; st.pop_back(); } } // Print rep(c1,0,10){ if(NUM[c1] != 0)cout << c1 << " " << NUM[c1] << "\n"; } rep(c1,0,52){ if(CH[c1] != 0)cout << alfa[c1] << " " << CH[c1] << "\n"; } return 0; }