Submission #1315871

#TimeUsernameProblemLanguageResultExecution timeMemory
1315871WH8Railway Trip 2 (JOI22_ho_t4)C++20
100 / 100
427 ms76076 KiB
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pll pair<long long, long long>
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define endl '\n'
#define ld long double
#define sz(x) static_cast<int>((x).size())
#define i5 tuple<int,int,int,int,int>
#define all(x) x.begin(), x.end()
#define iiii tuple<int, int,int,int>
#define ld long double
#define lol pair<pll,pll>
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

struct node {
	int s, e, m;
	lol v;
	node *l, *r;
	lol combine(lol a, lol b){
		return mp(min(a.f, b.f), max(a.s, b.s));
	}
	node (int S, int E, vector<pll> & V){
		s=S, e=E, m=(s+e)/2;
		if(s!=e){
			l=new node(s, m, V);
			r=new node(m+1, e, V);
			v=combine(l->v, r->v);
		}
		else {
			v.f.f=V[s].f;
			v.f.s=s;
			v.s.f=V[s].s;
			v.s.s=s;
		}
			//printf("segment %lld to %lld, {%lld %lld} {%lld %lld}\n", s,e,v.f.f,v.f.s,v.s.f,v.s.s);
	}
	lol qry(int S,int E){
		if((S==s and E==e) or s==e){
			return v;
		}
		if(E<=m)return l->qry(S,E);
		if(S>m)return r->qry(S,E);
		return combine(l->qry(S,m),r->qry(m+1,E));
	}
} *root;



signed main(){
	int n,k,m;cin>>n>>k>>m;
	vector<pll> v(n+1);
	for(int i=0;i<=n;i++)v[i]=make_pair(i,i);
	vector<tuple<int,int,int,int>> ed;

	vector<vector<pll>> st(n+1), en(n+1);
	for(int i=0;i<m;i++){
		int a, b;cin>>a>>b;
		int l=min(a, b), r=max(a, b), ul, ur;
		if(a < b) ul=a, ur=min(r, a+k-1);
		else ul=max(l, a-k+1), ur=a;
		ed.pb(make_tuple(ul, ur, l, r));
		//printf("ul %lld ur %lld, l %lld r %lld\n", ul, ur, l, r);
		st[ul].pb(mp(i, (a<b)));
		en[ur].pb(mp(i, (a<b)));
	}
	// sweep to calculate the extent of reach of each index. 
	array<multiset<int>, 2> ms;
	for(int i=1;i<=n;i++){
		for(auto [ind, t] : st[i]){
			int l=(t==0 ? get<2>(ed[ind]): get<3>(ed[ind]));
			ms[t].insert(l);
		}
		v[i].f = min(i, (ms[0].empty() ? n : *ms[0].begin()));
		v[i].s = max(i, (ms[1].empty() ? 0 : *prev(ms[1].end())));
		for(auto [ind,t] : en[i]){
			int l=(t==0 ? get<2>(ed[ind]): get<3>(ed[ind]));
			ms[t].erase(ms[t].find(l));
		}
	}
	//for(int i=1;i<=n;i++){printf("i %lld, l %lld, r %lld\n", i, v[i].f, v[i].s); }
	root=new node(1, n, v);
	// calculate the mn, mnindex, mx mxindex of each guy by segment tree 
	vector<pair<int,int>> to(n+1, {0,0});
	vector<vector<pll>> up(n+1, vector<pll>(20));
	for (int i=1;i<=n;i++){ auto [mn, mx]=root->qry(v[i].f, v[i].s);
		up[i][0].f=mn.s, up[i][0].s=mx.s; 
		//printf("up[%lld][0].f is %lld and [1].s is %lld\n", i, up[i][0].f, up[i][0].s);
	}

	// do twok decomp on each guy 
	auto merge=[&](int a, int b, int p)->pll{
		pll ret={-1, -1};
		if(v[up[a][p].f].f <= v[up[b][p].f].f){
			ret.f=up[a][p].f;
		}
		else {
			ret.f=up[b][p].f;
		}
		if(v[up[a][p].s].s >= v[up[b][p].s].s){
			ret.s=up[a][p].s;
		}
		else {
			ret.s=up[b][p].s ;
		}
		return ret;
	};
	for (int j=1;j<20;j++){
		for(int i=1;i<=n;i++){
			// two guys are up[i][j-1].f up[i][j-1].s 
			up[i][j]=merge(up[i][j-1].f, up[i][j-1].s, j-1);
		}
	}
	// binary lift to find cost for each query. 
	int q;cin>>q;
	while(q--){
		int s, t, cost=1;cin>>s>>t;
		if(v[s].f <= t and t <= v[s].s){
			cout<<cost<<'\n';
			continue;
		}
		pll cur={s, s};
		for(int j=19;j>=0;j--){
			pll temp=merge(cur.f, cur.s, j);
			//printf("cur %lld %lld j is %lld, temp is %lld %lld\n", cur.f, cur.s, j, temp.f, temp.s);
			if(v[temp.f].f <= t and v[temp.s].s >= t) continue;
			cur=temp;
			cost += (1<<j);
			//printf("cur %lld %lld j is %lld, temp is %lld %lld\n", cur.f, cur.s, j, temp.f, temp.s);
		}
		if(cost < n) cout<<cost+1<<'\n';
		else cout<<-1<<'\n';
	}
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...