#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// range chmin
// point get
struct dual_segmenttree{
private:
int n;
vector<int> node;
public:
dual_segmenttree() = default;
dual_segmenttree(int _n, vector<int> &init){
n = 1;
while(n < _n){
n *= 2;
}
node.resize(2 * n, 1e9);
for(int i = 0; i < _n; i++){
node[n + i] = init[i];
}
}
// [l, r) <- chmin(val)
void update(int l, int r, int val){
l += n;
r += n;
while(l < r){
if(l % 2 == 1){
node[l] = min(node[l], val);
l++;
}
if(r % 2 == 1){
r--;
node[r] = min(node[r], val);
}
l >>= 1;
r >>= 1;
}
return;
}
int get(int pos){
pos += n;
int res = 1e9;
while(pos >= 1){
res = min(res, node[pos]);
pos >>= 1;
}
return res;
}
};
vector<int> find_naive(int n, long long k, vector<long long> &a){
vector<int> res(n, n);
for(int i = 0; i < n; i++){
long long s = 0;
if(a[i] < 0){
res[i] = i + 1;
continue;
}
for(int j = i; j < n; j++){
if(a[j] > 0){
s += a[j];
s %= k;
}
else{
if(s + a[j] <= 0){
res[i] = j;
break;
}
s += a[j];
}
}
}
return res;
}
vector<int> find_right(int n, long long k, vector<long long> &a){
vector<long long> s(n + 1, 0);
for(int i = 0; i < n; i++){
s[i + 1] = s[i] + a[i];
s[i + 1] %= k;
if(s[i + 1] < 0){
s[i + 1] += k;
}
}
vector<pair<long long, int>> v;
for(int i = 0; i < n + 1; i++){
v.emplace_back(s[i], i);
}
sort(v.begin(), v.end());
vector<int> inv(n + 1), init(n + 1, n);
for(int i = 0; i < n + 1; i++){
inv[v[i].second] = i;
}
dual_segmenttree seg(n + 1, init);
vector<int> res(n, n);
for(int i = n - 1; i >= 0; i--){
if(a[i] > 0){
res[i] = seg.get(inv[i]);
continue;
}
res[i] = i + 1;
if(-a[i] >= k){
seg.update(0, n + 1, i);
continue;
}
long long left = (s[i] + a[i] + k) % k, right = s[i];
// [left, right]
// [l, r]
auto work = [&](long long l, long long r){
pair<long long, int> tar = {l, -1};
int idx_l = lower_bound(v.begin(), v.end(), tar) - v.begin();
tar = {r + 1, -1};
int idx_r = lower_bound(v.begin(), v.end(), tar) - v.begin();
seg.update(idx_l, idx_r, i);
return;
};
if(left <= right){
work(left, right);
}
else{
work(left, k - 1);
work(0, right);
}
}
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
long long k;
cin >> n >> q >> k;
int lg = 20;
vector<long long> a(n);
vector<long long> sum(n + 1, 0);
for(int i = 0; i < n; i++){
cin >> a[i];
if(i % 2 == 1){
a[i] *= -1;
}
sum[i + 1] = sum[i] + a[i];
}
vector<int> right = find_right(n, k, a);
auto make_doubling = [&](vector<long long> &sum, vector<int> &right){
vector<vector<pair<int, long long>>> res(lg, vector<pair<int, long long>>(n));
for(int i = 0; i < n; i++){
res[0][i] = {right[i], max(0LL, sum[right[i]] - sum[i]) / k};
}
for(int j = 1; j < lg; j++){
for(int i = 0; i < n; i++){
auto [pos, val] = res[j - 1][i];
if(pos == n){
res[j][i] = res[j - 1][i];
continue;
}
auto [pos2, val2] = res[j - 1][pos];
res[j][i] = {pos2, val + val2};
}
}
return res;
};
auto doubling = make_doubling(sum, right);
auto calc = [&](int l, int r, vector<vector<pair<int, long long>>> &doubling, vector<long long> &sum){
long long res = 0;
int pos = l;
for(int j = lg - 1; j >= 0; j--){
auto [nxt, val] = doubling[j][pos];
if(nxt <= r){
res += val;
pos = nxt;
}
if(pos == r){
break;
}
}
res += max(0LL, sum[r] - sum[pos]) / k;
return res;
};
auto naive = [&](int l, int r, vector<long long> &val){
long long res = 0;
long long s = 0;
for(int i = l; i < r; i++){
s += val[i];
s = max(0LL, s);
res += s / k;
s %= k;
}
return res;
};
for(int i = 0; i < q; i++){
int l, r;
cin >> l >> r;
l--;
if(l % 2 == 1){
l++;
}
if(l == r){
cout << 0 << "\n";
}
else{
cout << calc(l, r, doubling, sum) << "\n";
}
}
}