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
| #include <bits/stdc++.h> using namespace std; #define int long long const int N=500010; int n,m,k,a[N],sum[N],pre[N],f[N][21],g[N][21]; struct node{int l,r,x;bool operator<(const node &a)const{return l<a.l;}}; set<node>s; using sti=set<node>::iterator; sti split(int pos){ sti it=s.lower_bound({pos,0,0}); if(it!=s.end()&&it->l==pos)return it; --it; if(it->r<pos)return s.end(); int l=it->l,r=it->r,x=it->x; s.erase(it); s.insert({l,pos-1,x}); return s.insert({pos,r,x}).first; } void assign(int l,int r,int x){ l=max(l,0ll),r=min(r,k-1); if(l>r)return ; sti itr=split(r+1); sti itl=split(l); s.erase(itl,itr); s.insert({l,r,x}); } signed main(){ scanf("%lld%lld%lld",&n,&m,&k); for(int i=1;i<=n;i++)scanf("%lld",a+i); for(int i=1;i<=n;i++){ if(i&1^1)a[i]=-a[i]; sum[i]=((sum[i-1]+a[i])%k+k)%k; pre[i]=pre[i-1]+a[i]; } s.insert({0,k-1,n+1}); for(int i=n;i;i--){ if(i&1^1){ assign(sum[i-1]+a[i],sum[i-1],i); assign(max(sum[i-1]+a[i]+k,sum[i-1]+1),k-1,i); } f[i][0]=prev(s.upper_bound({sum[i-1],0,0}))->x+1; g[i][0]=(pre[f[i][0]-2]-pre[i-1])/k; } for(int i=0;i<=20;i++)f[n+1][i]=f[n+2][i]=n+2; for(int j=1;j<=20;j++)for(int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1],g[i][j]=g[i][j-1]+g[f[i][j-1]][j-1]; while(m--){ int l,r,res=0; scanf("%lld%lld",&l,&r); for(int i=20;~i;i--)if(f[l][i]<=r+1&&l<=r) res+=g[l][i],l=f[l][i]; printf("%lld\n",res+(l<=r?(pre[r]-pre[l-1])/k:0)); } return 0; }
|