#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
class sparse_segment_tree {
struct node {
node *l, *r;
int x, lazy;
node() : x(inf), lazy(-1), l(nullptr), r(nullptr) {}
~node() {
delete l;
delete r;
}
};
node *t;
int64_t n;
void push(node *t) {
t->l = t->l ? t->l : new node();
t->r = t->r ? t->r : new node();
if (t->lazy != -1) {
t->x = t->lazy;
t->l->lazy = t->lazy;
t->r->lazy = t->lazy;
t->lazy = -1;
}
}
void pull(node *t) {
t->x = min(t->l->x, t->r->x);
}
void set(node *t, int64_t tl, int64_t tr, int64_t l, int64_t r, int x) {
push(t);
if (tr < l || r < tl) return;
if (l <= tl && tr <= r) {
t->lazy = x;
push(t);
return;
}
int64_t tm = midpoint(tl, tr);
set(t->l, tl, tm, l, r, x);
set(t->r, tm + 1, tr, l, r, x);
pull(t);
}
int at(node *t, int64_t tl, int64_t tr, int64_t i) {
push(t);
if (tr < i || i < tl) return inf;
if (i <= tl && tr <= i) return t->x;
int64_t tm = midpoint(tl, tr);
return min(at(t->l, tl, tm, i), at(t->r, tm + 1, tr, i));
}
public:
sparse_segment_tree(int64_t n) : n(n), t(new node()) {}
~sparse_segment_tree() { delete t; }
void set(int64_t l, int64_t r, int x) {
if (l <= r) {
set(t, 0, n - 1, l, r, x);
} else {
set(t, 0, n - 1, l, n - 1, x);
set(t, 0, n - 1, 0, r, x);
}
}
int at(int64_t i) { return at(t, 0, n - 1, i); }
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, q;
int64_t k;
cin >> n >> q >> k;
vector<int64_t> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
if (i & 1) {
a[i] = -a[i];
}
}
vector<int64_t> pa(n + 1);
partial_sum(a.begin(), a.end(), pa.begin() + 1);
const int w = bit_width(unsigned(n));
vector lift(w, vector<int>(n + 1));
vector table(w, vector<int64_t>(n + 1));
auto modk = [&](int64_t x) { return ((x % k) + k) % k; };
sparse_segment_tree st(k);
for (int i = n - 1, small = n; i >= 0; --i) {
if (a[i] < 0) {
int64_t lo = modk(-pa[i]), hi = modk(-pa[i] - a[i] - 1);
st.set(lo, hi, i);
}
if (a[i] <= -k) {
small = i;
}
int j = min(small, st.at(modk(-pa[i])));
lift[0][i] = min(n, j + 1);
table[0][i] = (pa[j] - pa[i]) / k;
}
lift[0][n] = n;
for (int bt = 1; bt < w; ++bt) {
for (int i = 0; i <= n; ++i) {
lift[bt][i] = lift[bt - 1][lift[bt - 1][i]];
table[bt][i] = table[bt - 1][i] + table[bt - 1][lift[bt - 1][i]];
}
}
auto query = [&](int l, int r) {
r++;
int64_t ans = 0;
for (int bt = w - 1; bt >= 0; --bt) {
if (lift[bt][l] <= r) {
ans += table[bt][l];
l = lift[bt][l];
}
}
return ans + (pa[r] - pa[l]) / k;
};
while (q--) {
int l, r;
cin >> l >> r;
--l, --r;
cout << query(l, r) << '\n';
}
}