Submission #909523

# Submission time Handle Problem Language Result Execution time Memory
909523 2024-01-17T08:37:07 Z daoquanglinh2007 Birthday gift (IZhO18_treearray) C++17
0 / 100
1 ms 352 KB
#include <bits/stdc++.h>
using namespace std;

#define pii pair <int, int>
#define fi first
#define se second
#define mp make_pair

const int NM = 2000, LOG = 18, BL = 50;

int n, m, q;
vector <int> adj[NM+5];
int dep[NM+5], timer = 0, tin[NM+5], tout[NM+5];
pii f[LOG+5][2*NM+5];
int lg[2*NM+5];
int a[NM+5], g[NM/BL+5];
bool ok[NM/BL+5][NM+5];
int pref[NM+5], suff[NM+5];
vector <int> arr[NM/BL+5];

void dfs(int u, int p){
	dep[u] = (p == -1 ? 0 : dep[p]+1);
	tin[u] = ++timer;
	f[0][timer] = mp(dep[u], u);
	for (int v : adj[u]){
		if (v == p) continue;
		dfs(v, u);
		f[0][++timer] = mp(dep[u], u);
	}
	tout[u] = timer;
}

void build_sparse(){
	for (int i = 1; i <= LOG; i++)
		for (int j = 1; j+(1<<i)-1 <= timer; j++)
			f[i][j] = min(f[i-1][j], f[i-1][j+(1<<(i-1))]);
			
	lg[1] = 0;
	for (int i = 2; i <= timer; i++)
		lg[i] = lg[i>>1]+1;
}

int lca(int u, int v){
	int l = tin[u], r = tin[v];
	if (l > r) swap(l, r);
	int k = lg[r-l+1];
	return min(f[k][l], f[k][r-(1<<k)+1]).se;
}

void build(int id){
	for (int v : arr[id]) ok[id][v] = 0;
	arr[id].clear();
	
	for (int i = id*BL; i < min((id+1)*BL, m); i++){
		int cur = a[i];
		for (int j = i; j < min((id+1)*BL, m); j++){
			cur = lca(cur, a[j]);
			if (ok[id][cur]) break;
			ok[id][cur] = 1;
			arr[id].push_back(cur);
		}
		if (i == id*BL) g[id] = cur;
	}
	pref[id*BL] = a[id*BL];
	for (int i = id*BL+1; i < min((id+1)*BL, m); i++)
		pref[i] = lca(pref[i-1], a[i]);
	suff[min((id+1)*BL, m)-1] = a[min((id+1)*BL, m)-1];
	for (int i = min((id+1)*BL, m)-2; i >= id*BL; i--)
		suff[i] = lca(suff[i+1], a[i]);
}

void preprocess(){
	for (int i = 0; i*BL < m; i++){
		build(i);
	}
}

void update(int x, int val){
	a[x] = val;
	build(x/BL);
}

bool is_ancestor(int a, int u){
	return tin[a] <= tin[u] && tout[a] >= tout[u];
}

pii manual_query(int l, int r, int v){
	for (int i = l; i <= r; i++)
		if (is_ancestor(v, a[i])){
			int cur = a[i], j = i;
			while (j < r){
				int ne = lca(cur, a[j+1]);
				if (is_ancestor(v, ne)){
					cur = ne;
					j++;
				}
				else break;
			}
			if (cur == v) return mp(i, j);
			i = j;
		}
	return mp(-1, -1);
}

pii query(int l, int r, int v){
	int L = (l+BL-1)/BL, R = (r-BL+1)/BL;
	if (l/BL == r/BL || L > R){
		return manual_query(l, r, v);
	}
	for (int i = L; i <= R; i++)
		if (ok[i][v]){
			return manual_query(i*BL, min((i+1)*BL, m)-1, v);
		}
	pii tmp = manual_query(l, L*BL-1, v);
	if (tmp.fi != -1) return tmp;
	tmp = manual_query((R+1)*BL, r, v);
	if (tmp.fi != -1) return tmp;
	
	for (int i = L; i <= R+1; i++)
		if (i <= R && is_ancestor(v, g[i])){
			int j = i, cur = g[i];
			while (j < R){
				int ne = lca(cur, g[j+1]);
				if (is_ancestor(v, ne)){
					cur = ne;
					j++;
				}
				else break;
			}
			int lo = max(l, (i-1)*BL), hi = i*BL-1, resl = i*BL;
			while (lo <= hi){
				int mid = (lo+hi)/2;
				if (is_ancestor(v, suff[mid])){
					resl = mid;
					hi = mid-1;
				}
				else lo = mid+1;
			}
			if (resl < i*BL) cur = lca(cur, suff[resl]);
			
			lo = (j+1)*BL, hi = min(r, (j+2)*BL-1);
			int resr = (j+1)*BL-1;
			while (lo <= hi){
				int mid = (lo+hi)/2;
				if (is_ancestor(v, pref[mid])){
					resr = mid;
					lo = mid+1;
				}
				else hi = mid-1;
			}
			if (resr >= (j+1)*BL) cur = lca(cur, pref[resr]);
			
			if (cur == v) return mp(resl, resr);
			
			i = j;
		}
		else{
			int lo = max(l, (i-1)*BL), hi = min(r, i*BL-1), resl = -1;
			while (lo <= hi){
				int mid = (lo+hi)/2;
				if (is_ancestor(v, suff[mid])){
					resl = mid;
					hi = mid-1;
				}
				else lo = mid+1;
			}
			lo = max(l, i*BL), hi = min(r, (i+1)*BL-1); int resr = -1;
			while (lo <= hi){
				int mid = (lo+hi)/2;
				if (is_ancestor(v, pref[mid])){
					resr = mid;
					lo = mid+1;
				}
				else hi = mid-1;
			}
			if (resl != -1 && resr != -1){
				if (lca(suff[resl], pref[resr]) == v) return mp(resl, resr);
			}
		}
	return mp(-1, -1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	cin >> n >> m >> q;
	for (int i = 1; i < n; i++){
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dfs(1, -1);
	build_sparse();
	
	for (int i = 0; i < m; i++) cin >> a[i];
	preprocess();
	
	while (q--){
		int type; cin >> type;
		if (type == 1){
			int pos, val; cin >> pos >> val;
			update(pos-1, val);
		}
		else{
			int l, r, v; cin >> l >> r >> v;
			pii ans = query(l-1, r-1, v);
			if (ans.fi != -1) ans.fi++, ans.se++;
			cout << ans.fi << ' ' << ans.se << '\n';
		}
	}
	return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB n=5
2 Correct 1 ms 344 KB n=100
3 Correct 1 ms 348 KB n=100
4 Correct 1 ms 348 KB n=100
5 Correct 1 ms 348 KB n=100
6 Correct 1 ms 352 KB n=100
7 Correct 1 ms 348 KB n=100
8 Correct 1 ms 348 KB n=100
9 Correct 1 ms 348 KB n=100
10 Incorrect 1 ms 344 KB Wrong range.
11 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB n=5
2 Correct 1 ms 344 KB n=100
3 Correct 1 ms 348 KB n=100
4 Correct 1 ms 348 KB n=100
5 Correct 1 ms 348 KB n=100
6 Correct 1 ms 352 KB n=100
7 Correct 1 ms 348 KB n=100
8 Correct 1 ms 348 KB n=100
9 Correct 1 ms 348 KB n=100
10 Incorrect 1 ms 344 KB Wrong range.
11 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB n=5
2 Correct 1 ms 344 KB n=100
3 Correct 1 ms 348 KB n=100
4 Correct 1 ms 348 KB n=100
5 Correct 1 ms 348 KB n=100
6 Correct 1 ms 352 KB n=100
7 Correct 1 ms 348 KB n=100
8 Correct 1 ms 348 KB n=100
9 Correct 1 ms 348 KB n=100
10 Incorrect 1 ms 344 KB Wrong range.
11 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB n=5
2 Correct 1 ms 344 KB n=100
3 Correct 1 ms 348 KB n=100
4 Correct 1 ms 348 KB n=100
5 Correct 1 ms 348 KB n=100
6 Correct 1 ms 352 KB n=100
7 Correct 1 ms 348 KB n=100
8 Correct 1 ms 348 KB n=100
9 Correct 1 ms 348 KB n=100
10 Incorrect 1 ms 344 KB Wrong range.
11 Halted 0 ms 0 KB -