Language: C++

#include <bits/stdc++.h>
using namespace std;

#define times(n, i)      uptil(0, n, i)
#define rtimes(n, i)     downto((n) - 1, 0, i)
#define upto(f, t, i)    for(int _##i = (t), i = (f); i <= _##i; i++)
#define uptil(f, t, i)   for(int _##i = (t), i = (f); i <  _##i; i++)
#define downto(f, t, i)  for(int _##i = (t), i = (f); i >= _##i; i--)
#define downtil(f, t, i) for(int _##i = (t), i = (f); i >  _##i; i--)
typedef long double ld;
#define long long long

#if defined(EBUG) && !defined(ONLINE_JUDGE)
    #define debug true
    #define ln << endl
#else
    #define debug false
    #define ln << '\n'
#endif
#define tb << '\t'
#define sp << ' '

const int MOD = 1e9+7;

namespace sa {
constexpr unsigned sINT = sizeof(int);

inline void induced_sort(const int* const s, int n1, int* const sa, int** const bucref, int** const bucref1,
const int* const is_stype, const int* const lcount, int C, const int* lms, int clms) {
    int n = n1 - 1;
    memcpy(bucref1, bucref, sizeof(int*) * (C + 1));
    rtimes(clms, l) {
        int/*s.i*/j = lms[l];
        *--bucref1[s[j]+1] = j;
    }

    memcpy(bucref1, bucref, sizeof(int*) * (C + 1));
    times(n1, a) if(sa[a] > 0) {
        int/*s.i*/t = sa[a]-1;
        if(is_stype[t]) continue;
        *bucref1[s[t]]++ = t;
    }

    times(C, c) {
        int* d = bucref[c] + lcount[c];
        memset(d, -1, sINT * (bucref[c+1] - d));
    }

    memcpy(bucref1, bucref + 1, sizeof(int*) * C);
    rtimes(n1, a) if(sa[a] > 0) {
        int/*s.i*/t = sa[a]-1;
        if(!is_stype[t]) continue;
        *--bucref1[s[t]] = t;
    }
    sa[0] = n;
}

/*                       c[i]      i#           i[a]                a[c]                 a[c]*/
void sa_is(const int* const s, int n1, int* const sa, int** const bucref, int** const bucref1,
/*          a#[c]            i[l]  l[i](L:0,S\LMS:-1)                   i[l]*/
int* const lcount, int* const lms, int* const invlms1, int* const lms_sorted, int C) {
    int n = n1 - 1;
    if(debug) { times(n, j) assert(s[j] != 0); assert(s[n] == 0); }
    switch(n) {
        case 0: sa[0]=0; return; case 1: sa[0]=1; sa[1]=0; return;
        case 2: sa[0]=2; if(s[0] < s[1]) { sa[1]=0; sa[2]=1; } else { sa[1]=1; sa[2]=0; } return;
        case 3: sa[0]=3;
            int a = s[0]-s[1], b = s[1]-s[2], c = s[2]-s[0];
            if(a > 0) {
                if(c > 0)    { sa[1]=1; sa[2]=0; sa[3]=2; return; }
                if(b < 0)    { sa[1]=1; sa[2]=2; sa[3]=0; return; }
            } else if(b < 0) { sa[1]=0; sa[2]=1; sa[3]=2; return; }
            if(a < 0)
                if(c > 0)    { sa[1]=0; sa[2]=2; sa[3]=1; return; }
                else         { sa[1]=2; sa[2]=0; sa[3]=1; return; }
            sa[1]=2; sa[2]=1; sa[3]=0; return;
    }

    times(n1, j) ++bucref[s[j]+1];
    bucref[0] = sa;
    times(C, c) bucref[c+1] += (int)bucref[c] / sINT;

/********* check S-Type or L-Type *********/
    invlms1[n] = -1;
    rtimes(n, j) invlms1[j] = s[j] != s[j+1] ? -(s[j] < s[j+1]) : invlms1[j+1];
    times(n1, j) if(!invlms1[j]) ++lcount[s[j]]; // LType

/********* list up LMS *********/
    int/*l*/clms = 0;
    upto(1, n, j) if(!invlms1[j-1] && invlms1[j]) { // j-1: LType, j: SType
        lms[clms] = j;
        ++clms;
        invlms1[j] = clms;
        ++j; //: LS[?]
    }

/********* rough induced sort *********/
    induced_sort(s, n1, sa, bucref, bucref1, invlms1, lcount, C, lms, clms);
    int lsi = 0;
    times(n1, a) if(sa[a] >= 0 && invlms1[sa[a]] > 0 /*LMS*/) lms_sorted[lsi++] = sa[a];
    // assert(lsi == clms);

/********* SA-IS LMS-suffix *********/
    int lq = 0;
    int* const/*lms.c[l]*/lms_syms = sa;
    times(clms, l) {
        int j = lms_sorted[l], m1 = invlms1[j];
        if(l > 1) {
            int i = lms_sorted[l-1];
            if(lms[m1] - j == lms[invlms1[i]] - i) {
                int k = lms[m1] - j;
                ++lq;
                upto(0, k, h) if(s[j+h] != s[i+h]) { --lq; break; }
            }
        }
        lms_syms[m1-1] = l - lq;
    }
    int* const bc = bucref[C];
    int*/*l[e]*/lms_sa = sa + n1;
    sa_is(lms_syms, clms, lms_sa, bucref + C, bucref1, lcount + C,
        lms + clms, invlms1 + n1, lms_sorted + clms, clms - lq);
    bucref[C] = bc;

/********* strict induced sort *********/

    memset(sa, -1, n1 * sINT); // fill(sa, sa + n1, -1);

    times(clms, e) lms_sa[e] =  lms[lms_sa[e]];
    /* now lms_sa is: i[e] */
    induced_sort(s, n1, sa, bucref, bucref1, invlms1, lcount, C, lms_sa, clms);
}

bool inited = false;
int *saG, **brG, **br1G, *lcG, *lmsG, *il1G, *lsoG;
void init(int N1, int C) { // memory used: (8.5N+3C+3)*4bytes
    if(inited) return; inited = true;
    saG = new int[N1*2]; brG = new int*[C+N1+1]; br1G = new int*[max(N1/2,C)+1];
    lcG = new int[C+N1+1]; lmsG = new int[N1]; il1G = new int[N1*2]; lsoG = new int[N1];
}
void is_k(const int* const s, int n1, int c) {
    bool gs = false;
    if(n1 * 3 < c) {
        gs = n1 < 50;
        if(!gs) {
            int b = s[n1/3 + 1], a = 0;
            times(n1, i) a += s[i] == b;
            gs = a < n1 / a;
        }
    }
    if(debug) assert(inited);
    if(gs) {
        times(n1, i) saG[i] = i;
        sort(saG, saG + n1, [&](int i, int j) {
            if(i == j) return false;
            while(s[i] == s[j]) { ++i; ++j; }
            return s[i] < s[j];
        });
    } else {
        memset(saG, -1, n1*2*sINT); memset(brG, 0, (n1+c+1)*sINT); memset(lcG, 0, (n1+c+1)* sINT);
        sa_is(s, n1, saG, brG, br1G, lcG, lmsG, il1G, lsoG, c);
    }
}
void done() { inited = false; if(debug) cerr << "WARNING: void sa::done() does nothing." << endl; }
}

int s[200005], N;
map<long, array<long, 26>> c;

signed main() { // long: 64bit
    if(!debug) {
        cin.tie(0);
        ios::sync_with_stdio(0);
    }

    string S; cin >> S;
    N = S.size();
    long L, R; cin >> L >> R;

    sa::init(N + 1, 27);
    times(N, i) {
        s[i] = S[i] - 'a' + 1;
    }
    s[N] = 0;
    sa::is_k(s, N + 1, 27);
    long p0;
    times(N+1, i) if(sa::saG[i] == 0) {
        while(i >= 0 && sa::saG[--i] <= N / 2);
        if(i >= 0)
            p0 = sa::saG[i];
        else
            p0 = N;
        break;
    }
    if(debug) cout << p0 ln;

    times(26, i) c[0][i] = 0;
    times(N, j) times(26, i) {
        c[-j-1][i] = c[-j][i] + (S[j] == 'a' + i);
    }
    {
        long p2 = p0, q2 = N, p1 = p2 + q2 / 2, q1 = p2 * 2;
        times(26, i) {
            c[-p1][i] = c[-p2][i] + c[-q2][i] / 2;
            c[-q1][i] = c[-p2][i] * 2;
        }
        while(q1 < R) {
            long p = p1 + p2, q = q1 + q2;
            times(26, i) {
                c[-p][i] = c[-p1][i] + c[-p2][i];
                c[-q][i] = c[-q1][i] + c[-q2][i];
            }
            p2 = p1; p1 = p;
            q2 = q1; q1 = q;
        }
    }
    if(debug) {
        for(const auto& x: c) {
            cout << x.first tb;
            times(26, i) cout << x.second[i] sp;
            cout ln;
        }
    }

    long l[26], r[26];
    times(26, i) l[i] = r[i] = 0;
    if(debug) cout << "L\n";
    while(L > 0) {
        auto x = c.lower_bound(-L);
        L += x->first;
        times(26, i) l[i] += x->second[i];
        if(debug) {
            cout << L tb;
            times(26, i) cout << l[i] sp;
            cout ln;
        }
    }
    if(debug) cout << "R\n";
    ++R;
    while(R > 0) {
        auto x = c.lower_bound(-R);
        R += x->first;
        times(26, i) r[i] += x->second[i];
        if(debug) {
            cout << R tb;
            times(26, i) cout << r[i] sp;
            cout ln;
        }
    }

    times(26, i) {
        if(i) cout sp;
        cout << r[i] - l[i];
    }
    cout ln;

    return 0;
}


Compiler output:
a.cc: In function 'void sa::sa_is(const int*, int, int*, int**, int**, int*, int*, int*, int*, int)':
a.cc:81:32: error: cast from 'int*' to 'int' loses precision [-fpermissive]
   81 |     times(C, c) bucref[c+1] += (int)bucref[c] / sINT;
      |                                ^~~~~~~~~~~~~~