1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include <bits/stdc++.h> using namespace std; const int N = 1e6 + 5,Sz = N << 2; typedef long long ll; const ll INF = 0x3f3f3f3f3f3f3f3f; template<typename T> inline void ckmin(T &x,const T &y) { if(x > y) x = y;} template<typename T> inline void ckmax(T &x,const T &y) { if(x < y) x = y;} int n,m,p,a[N];
struct node{ int l,r,len; ll sum; vector<ll> c; }; node tr[Sz]; #define ls k << 1 #define rs k << 1 | 1 inline void pushup(int k) { tr[k].sum = tr[ls].sum + tr[rs].sum; for(int x = 0,y = 0;x <= tr[ls].len;x++) { if(y > tr[rs].len) --y; for(;y <= tr[rs].len;++y) { ll val = tr[rs].c[y] + 1ll * x * p - tr[ls].sum; ll lim = tr[ls].c[x + 1] - 1 - 1ll * x * p + tr[ls].sum; if(lim < tr[rs].c[y]) {if(y) --y;break; } ckmin(tr[k].c[x + y],max(tr[ls].c[x],val)); } } } void build(int k,int l,int r) { tr[k].l = l;tr[k].r = r; tr[k].len = r - l + 1; for(int i = 1;i <= tr[k].len + 2;i++) tr[k].c.push_back(INF); tr[k].c[0] = -INF; if(l == r) { tr[k].sum = a[l];tr[k].c[1] = p - a[l];return;} int mid = l + r >> 1; build(k << 1,l,mid); build(k << 1 | 1,mid + 1,r); pushup(k); } ll Now; void Query(int k,int l,int r,int x,int y) { if(l > y || r < x) return; if(x <= l && r <= y) { int pos = upper_bound(tr[k].c.begin(),tr[k].c.end(),Now) - tr[k].c.begin() - 1; Now = Now - 1ll * pos * p + tr[k].sum; return; } int mid = l + r >> 1; Query(k << 1,l,mid,x,y); Query(k << 1 | 1,mid + 1,r,x,y); } int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin >> n >> m >> p; for(int i = 1;i <= n;i++) cin >> a[i]; build(1,1,n); for(int i = 1;i <= m;i++) { int l,r; cin >> l >> r; Now = 0; Query(1,1,n,l,r); cout << Now << endl; } return 0; }
|