#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define ull unsigned long long
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace __gnu_pbds;
using namespace std;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll los(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;
const int tree_siz = 1024*4096-1;
int min_[tree_siz+1];
void seg_min(int akt, int p1, int p2, int s1, int s2, int x)
{
if(p2 < s1 || p1 > s2) return;
if(p1 >= s1 && p2 <= s2)
{
min_[akt] = min(min_[akt],x);
return;
}
seg_min(akt*2,p1,(p1+p2)/2,s1,s2,x);
seg_min(akt*2+1,(p1+p2)/2+1,p2,s1,s2,x);
}
int get_min(int p)
{
int v = tree_siz/2+1+p;
int ans = 1e9;
while(v != 1)
{
ans = min(ans,min_[v]);
v /= 2;
}
return min(ans,min_[1]);
}
int n,q;
ll k;
ll pref[500003];
ll pref_rel[500003];
ll arr[500003];
int opt[500003];
vector<pll> segs[500003];
pll jump[500006][19];
int main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//random_start();
cin >> n >> q >> k;
rep2(i,1,n) cin >> arr[i];
rep3(i,2,n,2) arr[i] *= -1;
rep2(i,1,n) pref[i] = (pref[i-1] + k*(ll)1e9+arr[i])%k;
rep2(i,1,n) pref_rel[i] = pref_rel[i-1] + arr[i];
rep3(i,1,n,2)
{
arr[i+1] *= -1;
if(arr[i+1] >= k) segs[i] = {{0,k-1}};
else if(pref[i]%k >= arr[i+1]) segs[i] = {{(pref[i]%k)-arr[i+1],pref[i]%k}};
else
{
segs[i].pb({0,pref[i]%k});
segs[i].pb({(pref[i]%k)+k-arr[i+1],k-1});
}
arr[i+1] *= -1;
}
map<ll,int> mp;
rep3(i,1,n,2) forall(it,segs[i])
{
mp[it.ff] = 1;
mp[it.ss] = 1;
}
rep3(i,1,n,2) mp[pref[i-1]%k] = 1;
int cur = 1;
forall(it,mp) mp[it.ff] = cur++;
int end_ = n+1;
if(end_%2 == 0) end_++;
rep(i,tree_siz+1) min_[i] = end_-2;
for(int i = end_-2; i >= 1; i--)
{
forall(it,segs[i]) seg_min(1,0,tree_siz/2,mp[it.ff],mp[it.ss],i);
opt[i] = get_min(mp[pref[i-1]%k])+2;
}
rep3(i,1,n,2) jump[i][0] = {opt[i],(pref_rel[opt[i]-2]-pref_rel[i-1])/k};
jump[end_][0] = {end_,0};
rep2(bit,1,18) rep3(i,1,end_,2)
{
jump[i][bit].ff = jump[jump[i][bit-1].ff][bit-1].ff;
jump[i][bit].ss = jump[i][bit-1].ss+jump[jump[i][bit-1].ff][bit-1].ss;
}
rep(qq,q)
{
int l,r;
cin >> l >> r;
if(l%2 == 0) l++;
if(l > r)
{
cout << "0\n";
continue;
}
ll ans = 0;
for(int bit = 18; bit >= 0; bit--)
{
int new_l = jump[l][bit].ff;
if(new_l <= r)
{
ans += jump[l][bit].ss;
l = new_l;
}
}
ans += (pref_rel[min(opt[l]-2,r)]-pref_rel[l-1])/k;
cout << ans << "\n";
}
}