#include #include #include #include #include #define LIM 100011 #define SLIM 211 #define ll long long using namespace std; char s[LIM]; // forward ans ll fans0[SLIM][LIM]; ll fans1[SLIM][LIM]; ll fans2[SLIM][LIM]; // backward ans ll bans0[SLIM][LIM]; ll bans1[SLIM][LIM]; ll bans2[SLIM][LIM]; int N, Q, S; int idx[1<<26]; int values[LIM]; ll sums0[LIM]; ll sums1[LIM]; ll sums2[LIM]; int ct; int get_idx(int x) { if (!~idx[x]) idx[x] = ct++; return idx[x]; } ll ans0, ans1, ans2; void preprocess() { S = max(N/200, int(N/sqrt(Q))); int x; idx[x = 0] = -1; for (int i = 0; i < N; i++) { idx[x ^= 1 << s[i] - 'a'] = -1; } ct = 0; values[0] = get_idx(x = 0); for (int i = 0; i < N; i++) { values[i+1] = get_idx(x ^= 1 << s[i] - 'a'); } for (int i = 0; i*S <= N; i++) { for (int j = i*S; j <= N; j++) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; sums2[v] = 0; } ans0 = ans1 = ans2 = 0; for (int j = i*S; j <= N; j++) { int v = values[j]; fans0[i][j] = ans0 += sums0[v]; fans1[i][j] = ans1 += sums0[v]*j - sums1[v]; fans2[i][j] = ans2 += sums0[v]*j*j - sums1[v]*2*j + sums2[v]; sums0[v]++; sums1[v] += j; sums2[v] += j*(ll)j; } int end = min(N, i*S + S - 1); for (int j = end; j >= 0; j--) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; sums2[v] = 0; } ans0 = ans1 = ans2 = 0; for (int j = end; j >= 0; j--) { int v = values[j]; bans0[i][j] = ans0 += sums0[v]; bans1[i][j] = ans1 += sums1[v] - sums0[v]*j; bans2[i][j] = ans2 += sums0[v]*j*j - sums1[v]*2*j + sums2[v]; sums0[v]++; sums1[v] += j; sums2[v] += j*(ll)j; } } } ll solve0(int L, int R) { L--; int Li = (L+1)/S, Ri = (R-1)/S; if (Ri - Li <= 1) { // normal for (int j = L; j <= R; j++) { int v = values[j]; sums0[v] = 0; } ans0 = 0; for (int j = L; j <= R; j++) { int v = values[j]; ans0 += sums0[v]; sums0[v]++; } } else { int Lm = Li*S+S-1, Rm = Ri*S; ans0 = fans0[Li+1][R] + bans0[Ri-1][L] - fans0[Li+1][Rm-1]; for (int j = L; j <= Lm; j++) { int v = values[j]; sums0[v] = 0; } for (int j = Rm; j <= R; j++) { int v = values[j]; sums0[v] = 0; } for (int j = L; j <= Lm; j++) { int v = values[j]; sums0[v]++; } for (int j = Rm; j <= R; j++) { int v = values[j]; ans0 += sums0[v]; } } return ans0; } ll solve1(int L, int R) { L--; int Li = (L+1)/S, Ri = (R-1)/S; if (Ri - Li <= 1) { // normal for (int j = L; j <= R; j++) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; } ans1 = 0; for (int j = L; j <= R; j++) { int v = values[j]; ans1 += sums0[v]*j - sums1[v]; sums0[v]++; sums1[v] += j; } } else { int Lm = Li*S+S-1, Rm = Ri*S; ans1 = fans1[Li+1][R] + bans1[Ri-1][L] - fans1[Li+1][Rm-1]; for (int j = L; j <= Lm; j++) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; } for (int j = Rm; j <= R; j++) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; } for (int j = L; j <= Lm; j++) { int v = values[j]; sums0[v]++; sums1[v] += j; } for (int j = Rm; j <= R; j++) { int v = values[j]; ans1 += sums0[v]*j - sums1[v]; } } return ans1; } ll solve2(int L, int R) { L--; int Li = (L+1)/S, Ri = (R-1)/S; if (Ri - Li <= 1) { // normal for (int j = L; j <= R; j++) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; sums2[v] = 0; } ans2 = 0; for (int j = L; j <= R; j++) { int v = values[j]; ans2 += sums0[v]*j*j - sums1[v]*2*j + sums2[v]; sums0[v]++; sums1[v] += j; sums2[v] += j*(ll)j; } } else { int Lm = Li*S+S-1, Rm = Ri*S; ans2 = fans2[Li+1][R] + bans2[Ri-1][L] - fans2[Li+1][Rm-1]; for (int j = L; j <= Lm; j++) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; sums2[v] = 0; } for (int j = Rm; j <= R; j++) { int v = values[j]; sums0[v] = 0; sums1[v] = 0; sums2[v] = 0; } for (int j = L; j <= Lm; j++) { int v = values[j]; sums0[v]++; sums1[v] += j; sums2[v] += j*(ll)j; } for (int j = Rm; j <= R; j++) { int v = values[j]; ans2 += sums0[v]*j*j - sums1[v]*2*j + sums2[v]; } } return ans2; } // the following is adapted from the problem statement void decode(){ ll A = 0 ; // initialising first key ll B = 0 ; // initialising second key while( Q -- ) { int X, Y, type; scanf("%d%d%d", &X, &Y, &type); int L = ( X + A ) % N + 1; // decoding L int R = ( Y + B ) % N + 1; // decoding R // N is the length of the given string if (L > R) { // swap L and R int T = L; L = R; R = T; } ll ans = type == 0 ? solve0(L,R) : type == 1 ? solve1(L,R) : solve2(L,R); // calculate answer for current query printf("%lld\n", ans); A = B; // updating key A B = ans; // updating key B } } int main() { int z; scanf("%d", &z); while(z--) { scanf("%s%d", s, &Q); N = strlen(s); preprocess(); decode(); } }