제출 #1362679

#제출 시각아이디문제언어결과실행 시간메모리
1362679blopBall Machine (BOI13_ballmachine)C++20
4.84 / 100
255 ms36476 KiB
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template<class T>
using ordered_set = tree<T, null_type, less<T>, 
					rb_tree_tag, tree_order_statistics_node_update>;
template<class T, class U>
using ordered_map = tree<T, U, less<T>, rb_tree_tag,
					tree_order_statistics_node_update>;
#define ll long long
#define ld long double
#define MOD 998244353
#define MAXN 250000
#define SIZE 100
#define pb push_back

ll power(ll a, ll b){
	if (b == 0) return 1;
	ll res = power(a, b / 2);
	if (b % 2 == 1) return res * res % MOD * a % MOD;
	return res * res % MOD;
	
//	if (b % 2 == 1) return res * res * a;
//	return res * res;
}

int idx = 1;

void dfs(vector<vector<int>> &g, int curr, int par, vector<int> &order, vector<int> &childs, vector<int> &posToOrder){
	vector<pair<int, int>> arr;
	for (auto &p : g[curr]){
		if (par == p) continue;
		arr.pb({childs[p], p});
	}
	sort(arr.begin(), arr.end());
	for (auto &p : arr){
		dfs(g, p.second, curr, order, childs, posToOrder);
	}
	order[idx] = curr;
	posToOrder[curr] = idx;
	idx++;
}

void getChildNum(vector<vector<int>> &g, int curr, int par, vector<int> &childs){
	int minChild = curr;
	for (auto &p : g[curr]){
		if (p == par) continue;
		getChildNum(g, p, curr, childs);
		minChild = min(minChild, childs[p]);
	}
	childs[curr] = minChild;
}

int updet(vector<int> &segTree, int idx, int l, int r, int upVal){
	if (upVal == 0) return 0;
	if (l == r){
		segTree[idx] = 1;
		return l;
	}
	int mid = (r - l) / 2 + l;
	int take = min(upVal, (mid - l + 1) - segTree[idx * 2]);
	int last = updet(segTree, idx * 2, l, mid, take);
	upVal -= take;
	if (upVal != 0){
		last = updet(segTree, idx * 2 + 1, mid + 1, r, upVal);	
	}
	segTree[idx] = segTree[idx * 2] + segTree[idx * 2 + 1];
	return last;
}

int query(vector<int> &segTree, int idx, int l, int r, int pos){
	if (l == r) return segTree[idx];
	
	int mid = (r - l) / 2 + l;
	if (pos <= mid) return query(segTree, idx * 2, l, mid, pos);
	return query(segTree, idx * 2 + 1, mid + 1, r, pos);
}

void delet(vector<int> &segTree, int idx, int l, int r, int deletPos){
	if (l == r){
		segTree[idx] = 0;
		return;
	}
	int mid = (r - l) / 2 + l;
	if (deletPos <= mid) delet(segTree, idx * 2, l, mid, deletPos);
	else delet(segTree, idx * 2 + 1, mid + 1, r, deletPos);
	segTree[idx] = segTree[idx * 2] + segTree[idx * 2 + 1];
}

signed main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	int n, q;
	cin >> n >> q;
	vector<vector<int>> parents(n + 1, vector<int>(20, 0));
	vector<vector<int>> g(n + 1);
	int root;
	for (int i = 1; i <= n; i++){
		int a;
		cin >> a;
		parents[i][0] = a;
		if (a == 0) root = i;
		else{
			g[a].pb(i);
		}
	}
//	cout << "EY\n";
	for (int j = 1; j < 20; j++){
		for (int i = 1; i <= n; i++){
			int nextPos = parents[i][j - 1];
			parents[i][j] = parents[nextPos][j - 1];
		}
	}
//	cout << "EY\n";
	vector<bool> balls(n + 1, 0);
	vector<int> order(n + 1, -1);
	vector<int> posToOrder(n + 1);
	vector<int> childs(n + 1, n + 5);
//	cout << "TES\n";
	getChildNum(g, root, 0, childs);
	dfs(g, root, 0, order, childs, posToOrder);
	vector<int> segTree(4 * n, 0);
//	cout << "TES\n";
	while(q--){
		int type, k;
		cin >> type >> k;
		if (type == 1){
			int last = updet(segTree, 1, 1, n, k);
			cout << order[last] << "\n";
		}
		else{
			int cnt = 0;
			for (int i = 19; i >= 0; i--){
				int next = parents[k][i];
				if (next == 0) continue;
				int val = query(segTree, 1, 1, n, order[next]);
				if (val){
					cnt += (1 << i);
					k = next;
				}
			}
			delet(segTree, 1, 1, n, order[k]);
			cout << cnt << "\n";
		}
	}
	
	return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…