제출 #879203

#제출 시각아이디문제언어결과실행 시간메모리
879203samek08Railway Trip 2 (JOI22_ho_t4)C++17
16 / 100
2035 ms6344 KiB
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define rep(a,b) for (int a = 0; a < (b); ++a)
#define pb push_back
#define all(t) t.begin(), t.end()

const int MAXN = 1e5+5, base = (1<<17), rozmiar_drzewa = base * 2, INF = 1e9+50;
int n = 0, k = 0, m = 0, q = 0, a = 0, b = 0;
vector<int> tree_min;
vector<int> tree_max;
int lewy[MAXN];
int prawy[MAXN];

inline void update_min(int l, int p, int val)
{
	l = l + base - 1, p = p + base + 1;
	while(l / 2 != p / 2)
	{
		if(l % 2 == 0) tree_min[l+1] = min(tree_min[l+1],val);
		if(p % 2 == 1) tree_min[p-1] = min(tree_min[p-1],val);
		l /= 2, p /= 2;
	}
}

inline void update_max(int l, int p, int val)
{
	l = l + base - 1, p = p + base + 1;
	while(l / 2 != p / 2)
	{
		if(l % 2 == 0) tree_max[l+1] = max(tree_max[l+1],val);
		if(p % 2 == 1) tree_max[p-1] = max(tree_max[p-1],val);
		l /= 2, p /= 2;
	}
}

inline int query_min(int v)
{
	int res = INF;
	v += base;
	while(v > 0)
	{
		res = min(res,tree_min[v]);
		v /= 2;
	}
	return res;
}

inline int query_max(int v)
{
	int res = -INF;
	v += base;
	while(v > 0)
	{
		res = max(res,tree_max[v]);
		v /= 2;
	}
	return res;
}

inline int query_min2(int l, int p)
{
	l = l + base - 1, p = p + base + 1;
	int res = INF;
	while(l / 2 != p / 2)
	{
		if(l % 2 == 0) res = min(res,tree_min[l+1]);
		if(p % 2 == 1) res = min(res,tree_min[p-1]);
		l /= 2, p /= 2;
	}
	return res;
}

inline int query_max2(int l, int p)
{
	l = l + base - 1, p = p + base + 1;
	int res = -INF;
	while(l / 2 != p / 2)
	{
		if(l % 2 == 0) res = max(res,tree_max[l+1]);
		if(p % 2 == 1) res = max(res,tree_max[p-1]);
		l /= 2, p /= 2;
	}
	return res;
}


int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> k >> m;

	tree_min.assign(rozmiar_drzewa,INF);
	tree_max.assign(rozmiar_drzewa,-INF);
	rep(i,n)
	{
		tree_min[i+base] = i, tree_max[i+base] = i;
	}

	while(m--)
	{
		cin >> a >> b;
		--a,--b;
		if(a <= b) update_max(a,a+k-1,b);
		else update_min(a-k+1,a,b);
	}

	rep(i,n) lewy[i] = query_min(i);
	rep(i,n) prawy[i] = query_max(i);
	//rep(i,n) cout << lewy[i] << " " << prawy[i] << endl;

	tree_min.assign(rozmiar_drzewa,INF);
	tree_max.assign(rozmiar_drzewa,-INF);
	rep(i,n)
	{
		tree_min[i+base] = lewy[i], tree_max[i+base] = prawy[i];
	}
	for(int i = base - 1; i > 0; --i)
	{
		tree_min[i] = min(tree_min[i*2],tree_min[i*2+1]);
		tree_max[i] = max(tree_max[i*2],tree_max[i*2+1]);
	}

	cin >> q;
	while(q--)
	{
		cin >> a >> b;
		--a, --b;
		if(a == b)
		{
			cout << "0" << '\n';
			continue;
		}
		int akt_l = a, akt_p = a, wyn = -1;
		for(int i = 1; i < n; ++i)
		{
			int l = query_min2(akt_l,akt_p), p = query_max2(akt_l,akt_p);
			//cout << "akt L: " << akt_l << " akt P: " << akt_p <<  " L: " << l << " P: " << p << endl; 
			akt_l = l, akt_p = p;
			if(b >= akt_l and b <= akt_p)
			{
				wyn = i;
				break;
			}
		}
		cout << wyn << '\n';
	}

	return 0;
}
#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...