// Source: https://usaco.guide/general/io
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int long long
ll n, q, k;
ll a[500005], r[500005], pref[500005], cry[500005], pref2[500005];
ll par[20][500005], sm[20][500005];
struct node{
int s, e, m, val;
node *l, *r;
node (int _s, int _e){
s = _s, e = _e, m = (s + e) >> 1;
val = (ll)1e18;
l = r = nullptr;
}
void mc() {
if (s == e || l != nullptr) return;
l = new node(s, m);
r = new node(m + 1, e);
}
void upd (ll p, int v) {
if (s == e) {
val = min(val, v);
return;
}
mc();
if (p <= m) l->upd(p, v);
else r->upd(p, v);
val = min(l->val, r->val);
}
ll qry(ll a, ll b) {
if ((a == s && b == e) || l == nullptr) return val;
else if (b <= m) return l->qry(a, b);
else if (a > m) return r->qry(a, b);
else return min(l->qry(a, m), r->qry(m+1, b));
}
ll find(ll x, ll a) {
//cerr << s << ' ' << e << ' ' << x << ' ' << a << ' ' << val << '\n';
if (s == e) return val <= x ? s : 1e6;
if (val > x || a > e) return 1e6;
mc();
if (a > m) return r->find(x, a);
ll res = l->find(x, a);
if (res != 1e6) return res;
return r->find(x, m + 1);
}
}*root;
int32_t main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> q >> k;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) {
pref[i] = pref[i - 1] + a[i] * (i&1?1:-1), r[i] = 1e6;
pref2[i] = pref2[i - 1] + (i&1?a[i]%k:-a[i]);
cry[i] = cry[i - 1] + a[i]/k * (i&1);
}
vector <pair <ll, int> > up, qu;
for (int i = 1; i <= n; i += 2) {
up.push_back({(pref[i] % k + k) % k, i});
qu.push_back({(pref[i - 1] % k + k) % k, i});
}
sort(up.begin(), up.end());
sort(qu.begin(), qu.end());
int lst = (n & 1 ? n + 1 : n);
/*
vector <ll> disc;
for (int i = 1; i <= n; i += 2) {
disc.push_back(pref[i - 1] % k);
disc.push_back(pref[i] % k);
disc.push_back(pref[i] % k - 1);
disc.push_back(pref[i]%k - a[i + 1] % k);
disc.push_back(pref[i] % k - a[i + 1] % k + k);
}
sort(disc.begin(), disc.end());
disc.erase(unique(disc.begin(), disc.end()), disc.end());
*/
/*
for (int i = (n%2?n:n-1); i >= 1; i -= 2) {
//find first j >= i where it is not good to extend to j + 1
//basically (a[i] - a[i + 1] + a[i + 2] - a[i + 3] + ... + a[j])%k < a[j + 1]
//so it must be positive, and if pref[i] = a[1] - a[2] + a[3] - ... + a[i],
//then (pref[j] - pref[i - 1]) % k < a[j + 1] % k
//if pref[j] % k >= pref[i - 1] % k, then
//pref[j]%k - pref[i - 1]%k < a[j + 1]%k --> pref[i - 1] % k > pref[j] % k - a[j + 1] % k
//otherwise, pref[j]%k - pref[i - 1]%k + k < a[j + 1] % k --> pref[i - 1] % k > pref[j] % k - a[j + 1] % k + k
if (a[i + 1] >= k) lst = i + 1;
}
*/
//root = new node(0, (int)disc.size() + 5);
root = new node(1, n);
int ptr = 0;
for (auto [val, i] : qu) {
while (ptr < (int)up.size() && up[ptr].first < val) {
//ll qv = lower_bound(disc.begin(), disc.end(), up[ptr].first - a[up[ptr].second + 1] % k + k) - disc.begin() + 1;
//root->upd(qv, up[ptr].second);
root->upd(up[ptr].second, up[ptr].first - a[up[ptr].second + 1] + k);
ptr++;
}
//ll qv = lower_bound(disc.begin(), disc.end(), val - 1) - disc.begin() + 1;
//r[i] = min(r[i], root->qry(0, qv));
r[i] = min(r[i], root->find(val, i));
}
//cerr << "hi\n";
//for (int i = 1; i <= n; i++) cerr << r[i] << ' ';
//cerr << '\n';
reverse(up.begin(), up.end());
reverse(qu.begin(), qu.end());
//root = new node(0, (int)disc.size() + 5);
root = new node(1, n);
ptr = 0;
for (auto [val, i] : qu) {
while (ptr < (int)up.size() && up[ptr].first >= val) {
//ll qv = lower_bound(disc.begin(), disc.end(), up[ptr].first - a[up[ptr].second + 1] % k) - disc.begin() + 1;
//root->upd(qv, up[ptr].second);
//cerr << "UPDATE" << ' ' << up[ptr].second << ' ' << up[ptr].first - a[up[ptr].second + 1] << '\n';
root->upd(up[ptr].second, up[ptr].first - a[up[ptr].second + 1]);
ptr++;
}
//ll qv = lower_bound(disc.begin(), disc.end(), val - 1) - disc.begin() + 1;
//r[i] = min(r[i], root->qry(0, qv));
//cerr << "QUERY " << val << ' ' << i << '\n';
r[i] = min(r[i], root->find(val, i));
}
root = new node(0, n);
//cerr << "hi\n";
for (int i = n; i >= 1; i--) {
if (i % 2 == 0 && a[i] >= k) lst = i;
r[i] = min(r[i], (ll)lst - 1);
if (i % 2 == 0) root->upd(i, pref2[i]);
if (i & 1) r[i] = min(r[i], root->find(pref2[i - 1], i) - 1);
}
//i->r[i]
for (int i = 1; i <= n; i += 2) {
par[0][i] = r[i] + 2;
sm[0][i] = (pref[r[i]] - pref[i - 1]) / k;
}
for (int i = 2; i <= n; i += 2) par[0][i] = n + 1;
par[0][n + 1] = par[0][0] = n + 1;
for (int i = 1; i <= 19; i++) {
for (int j = 1; j <= n; j++) {
par[i][j] = par[i - 1][par[i - 1][j]];
sm[i][j] = sm[i - 1][j] + sm[i - 1][par[i - 1][j]];
}
}
//for (int i = 1; i <= n; i++) cerr << r[i] << ' ';
//cerr << '\n';
//why is this so hard
while (q--) {
int l, r1; cin >> l >> r1;
int cur = (l & 1 ? l : l + 1);
r1 = (r1 & 1 ? r1 : r1 - 1);
ll ans = 0;
/*
while (cur <= r1) {
int tmp = r[cur];
if (tmp > r1) {
int rb = (r1 & 1 ? r1 : r1 - 1);
ans += (pref[rb] - pref[cur - 1]) / k;
break;
}
else {
ans += (pref[tmp] - pref[cur - 1]) / k;
cur = tmp + 2;
}
}
*/
for (int i = 19; i >= 0; i--) {
if (par[i][cur] <= r1 && par[i][cur] >= 1) {
ans += sm[i][cur];
cur = par[i][cur];
}
}
if (cur <= r1) ans += (pref[r1] - pref[cur - 1]) / k;
cout << ans << '\n';
/*
ll ext = 0, cur = 0;
for (int i = l; i <= r; i++) {
if (i & 1) {
cur += (a[i] + ext) / k;
ext = (a[i] + ext) % k;
}
else {
ext = max(0ll, ext - a[i]);
}
}
cout << cur << '\n';
*/
}
}