#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
// - Từ thuật trâu O(q * n^2), ta thấy rằng bản chất của 2 vòng for là đang đi tính tổng của hình chữ nhật (l, l, r, r) của bảng dp
// - Do đó, ta có thể tối ưu theo 2 hướng như sau:
// * Hướng tối ưu 1: Prefix Sum 2D:
// - Ta có thể chuẩn bị trước mảng prefix sum 2D sum[x][y] của bảng dp trong O(n^2) và trả lời mỗi truy vấn tính tổng hình chữ nhật trong O(1)
// * Hướng tối ưu 2: DP Range:
// - Gọi ans[l][r] = Đáp án của đoạn [l, r] = Tổng của hình chữ nhật (l, l, r, r)
// - Ta có công thức như sau: ans[l][r] = ans[l + 1][r] + ans[l][r - 1] - ans[l + 1][r - 1] + (đóng góp của cặp (l, r))
const int N = 5e3 + 5;
int n, q;
string s;
bool dp[N][N]; // dp[l][r] = true/false = Xâu con s[l..r] có phải là xâu đối xứng hay không
int ans[N][N]; // ans[l][r] = Đáp án của đoạn [l, r]
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> s >> q;
n = s.size();
s = ' ' + s;
for (int l = n; l >= 1; l--) {
for (int r = l; r <= n; r++) {
if (l == r) {
dp[l][r] = 1;
continue;
}
if (l + 1 == r) {
dp[l][r] = (s[l] == s[r]);
continue;
}
dp[l][r] = (s[l] == s[r]) & (dp[l + 1][r - 1]);
}
}
for (int l = n; l >= 1; l--) {
for (int r = l; r <= n; r++) {
ans[l][r] = ans[l + 1][r] + ans[l][r - 1] - ans[l + 1][r - 1] + dp[l][r];
}
}
while (q--) {
int l, r;
cin >> l >> r;
cout << ans[l][r] << '\n';
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsgIAoKdHlwZWRlZiBsb25nIGxvbmcgbGw7ICAKdHlwZWRlZiBwYWlyPGludCwgaW50PiBpaTsgIAoKY29uc3QgaW50IElORiA9IDFlOTsgIApjb25zdCBsbCBMSU5GID0gMWUxODsgIAoKLy8gLSBU4burIHRodeG6rXQgdHLDonUgTyhxICogbl4yKSwgdGEgdGjhuqV5IHLhurFuZyBi4bqjbiBjaOG6pXQgY+G7p2EgMiB2w7JuZyBmb3IgbMOgIMSRYW5nIMSRaSB0w61uaCB04buVbmcgY+G7p2EgaMOsbmggY2jhu68gbmjhuq10IChsLCBsLCByLCByKSBj4bunYSBi4bqjbmcgZHAKLy8gLSBEbyDEkcOzLCB0YSBjw7MgdGjhu4MgdOG7kWkgxrB1IHRoZW8gMiBoxrDhu5tuZyBuaMawIHNhdToKLy8gKiBIxrDhu5tuZyB04buRaSDGsHUgMTogUHJlZml4IFN1bSAyRDogCi8vIC0gVGEgY8OzIHRo4buDIGNodeG6qW4gYuG7iyB0csaw4bubYyBt4bqjbmcgcHJlZml4IHN1bSAyRCBzdW1beF1beV0gY+G7p2EgYuG6o25nIGRwIHRyb25nIE8obl4yKSB2w6AgdHLhuqMgbOG7nWkgbeG7l2kgdHJ1eSB24bqlbiB0w61uaCB04buVbmcgaMOsbmggY2jhu68gbmjhuq10IHRyb25nIE8oMSkKLy8gKiBIxrDhu5tuZyB04buRaSDGsHUgMjogRFAgUmFuZ2U6Ci8vIC0gR+G7jWkgYW5zW2xdW3JdID0gxJDDoXAgw6FuIGPhu6dhIMSRb+G6oW4gW2wsIHJdID0gVOG7lW5nIGPhu6dhIGjDrG5oIGNo4buvIG5o4bqtdCAobCwgbCwgciwgcikKLy8gLSBUYSBjw7MgY8O0bmcgdGjhu6ljIG5oxrAgc2F1OiBhbnNbbF1bcl0gPSBhbnNbbCArIDFdW3JdICsgYW5zW2xdW3IgLSAxXSAtIGFuc1tsICsgMV1bciAtIDFdICsgKMSRw7NuZyBnw7NwIGPhu6dhIGPhurdwIChsLCByKSkgICAKY29uc3QgaW50IE4gPSA1ZTMgKyA1OyAKCmludCBuLCBxOyAgCnN0cmluZyBzOyAgCgpib29sIGRwW05dW05dOyAvLyBkcFtsXVtyXSA9IHRydWUvZmFsc2UgPSBYw6J1IGNvbiBzW2wuLnJdIGPDsyBwaOG6o2kgbMOgIHjDonUgxJHhu5FpIHjhu6luZyBoYXkga2jDtG5nCmludCBhbnNbTl1bTl07IC8vIGFuc1tsXVtyXSA9IMSQw6FwIMOhbiBj4bunYSDEkW/huqFuIFtsLCByXQoKaW50IG1haW4oKSB7Cglpb3M6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7IAoJY2luLnRpZShudWxscHRyKTsgCQoJY2luID4+IHMgPj4gcTsgCgluID0gcy5zaXplKCk7ICAKCXMgPSAnICcgKyBzOyAgCgoJZm9yIChpbnQgbCA9IG47IGwgPj0gMTsgbC0tKSB7CgkJZm9yIChpbnQgciA9IGw7IHIgPD0gbjsgcisrKSB7CgkJCWlmIChsID09IHIpIHsKCQkJCWRwW2xdW3JdID0gMTsgIAoJCQkJY29udGludWU7IAoJCQl9CgkJCWlmIChsICsgMSA9PSByKSB7CgkJCQlkcFtsXVtyXSA9IChzW2xdID09IHNbcl0pOyAKCQkJCWNvbnRpbnVlOyAKCQkJfQoJCQlkcFtsXVtyXSA9IChzW2xdID09IHNbcl0pICYgKGRwW2wgKyAxXVtyIC0gMV0pOyAKCQl9Cgl9CgoJZm9yIChpbnQgbCA9IG47IGwgPj0gMTsgbC0tKSB7CgkJZm9yIChpbnQgciA9IGw7IHIgPD0gbjsgcisrKSB7CgkJCWFuc1tsXVtyXSA9IGFuc1tsICsgMV1bcl0gKyBhbnNbbF1bciAtIDFdIC0gYW5zW2wgKyAxXVtyIC0gMV0gKyBkcFtsXVtyXTsgCgkJfQoJfQoKCXdoaWxlIChxLS0pIHsKCQlpbnQgbCwgcjsgCgkJY2luID4+IGwgPj4gcjsKCQljb3V0IDw8IGFuc1tsXVtyXSA8PCAnXG4nOyAKCX0KfQ==