#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld long double
#define show(x,y) cout << y << " " << #x << endl;
#define show2(x,y,i,j) cout << y << " " << #x << " " << j << " " << #i << endl;
#define show3(x,y,i,j,p,q) cout << y << " " << #x << " " << j << " " << #i << " " << q << " " << #p << endl;
#define show4(x,y) for(auto it:y) cout << it << " "; cout << #x << endl;
typedef pair<int,int>pii;
typedef pair<int,pii>pi2;
#define ll __int128
mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());
vector<pair<ll,ll>>adj[300005];
bool visited[300005];
int n,mod;
int arr[300005];
ll diff[300005];
ll val[300005]; //diagonal
ll prefix[300005];
ll prefix2[300005];
ll sum[300005];
bool rt[300005];
ll f(int l, int r){
ll hold=prefix2[r]-prefix2[l-1];
hold-=(r-l+1)*arr[r];
hold+=(sum[r]-sum[l])-l*(prefix[r]-prefix[l]);
return hold;
}
int two[22][300005];
ll dist[22][300005];
void dfs(int index, int par){
visited[index]=true;
for(int x=0;x<20;x++){
two[x+1][index]=two[x][two[x][index]];
dist[x+1][index]=dist[x][index]+dist[x][two[x][index]];
}
for(auto it:adj[index]){
if(it.first==par) continue;
two[0][it.first]=index;
dist[0][it.first]=it.second;
dfs(it.first,index);
}
}
inline int combine(int a, int b){
return max(a,b);
}
struct node{
int s,e,m;
node *l,*r;
int v;
node(int ss, int ee):s(ss),e(ee),m((s+e)>>1),v(0){
if(s!=e){
l=new node(s,m);
r=new node(m+1,e);
}
}
void upd(int x, int y){
if(s==e){
v=y;
return;
}
if(x<=m) l->upd(x,y);
else r->upd(x,y);
v=combine(l->v,r->v);
}
int query(int x, int y){
if(x<=s&&y>=e){
return v;
}
if(y<=m) return l->query(x,y);
if(x>m) return r->query(x,y);
return combine(l->query(x,m),r->query(m+1,y));
}
};
void solve(){
cin >> n >> mod;
int counter=0;
for(int x=1;x<=n;x++){
cin >> arr[x];
if(x>1){
diff[x]=((arr[x]-arr[x-1])%mod+mod)%mod;
counter+=diff[x];
}
val[x]=arr[x]+counter;
//cout << val[x] << " ";
}
//cout << "\n";
//for(int x=1;x<=n;x++) cout << diff[x] << " ";
//cout << "\n";
for(int x=1;x<=n;x++){
sum[x]=sum[x-1]+diff[x]*x;
prefix[x]=prefix[x-1]+diff[x];
prefix2[x]=prefix2[x-1]+arr[x];
}
deque<int>d;
node st(0,n+5);
for(int x=1;x<=n;x++){
while(!d.empty()&&val[d.back()]>=val[x]) d.pop_back();
int l=2;
int r=x;
int mid;
int best=r+1;
while(l<=r){
mid=(l+r)/2;
if(prefix[x]-prefix[mid-1]<=arr[x]){
best=mid;
r=mid-1;
}
else l=mid+1;
}
st.upd(x,best-1);
if(!d.empty()){
int nxt=d.back();
ll cost=f(nxt+1,x);
//cout << x << " " << nxt << " " << cost << " check\n";
adj[x].push_back({nxt,cost});
adj[nxt].push_back({x,cost});
}
d.push_back(x);
}
for(int x=1;x<=n;x++){
if(!visited[x]){
dfs(x,-1);
rt[x]=true;
}
}
int q;
cin >> q;
int temp,temp2;
for(int x=0;x<q;x++){
cin >> temp >> temp2;
if(st.query(temp,temp2)>temp){
cout << -1 << "\n";
continue;
}
ll ans=f(temp,temp2);
cout << (int)ans/mod << "\n";
}
}
int32_t main(){
ios::sync_with_stdio(0);
cin.tie(0);
//freopen("in.txt","r",stdin);
//freopen("in.txt","w",stdout);
int t=1;
//cin >> t;
while(t--){
solve();
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |