제출 #1138473

#제출 시각아이디문제언어결과실행 시간메모리
1138473LCJLYFish 3 (JOI24_fish3)C++20
35 / 100
821 ms255088 KiB
#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<int,ll>>adj[300005];
bool visited[300005];
int n,mod;
int arr[300005];
int diff[300005];
int val[300005]; //diagonal
int prefix[300005];
int 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=0;
		for(int y=19;y>=0;y--){
			if(two[y][temp2]<temp) continue;
			ans+=dist[y][temp2];
			temp2=two[y][temp2];
		}
		if(temp2>=temp){
			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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...