Submission #848989

# Submission time Handle Problem Language Result Execution time Memory
848989 2023-09-13T19:43:56 Z rainboy Beech Tree (IOI23_beechtree) C++17
Compilation error
0 ms 0 KB
#include "beechtree.h"
#include <cstdlib>
#include <cstring>

using namespace std;

typedef vector<int> vi;

const int N = 200000, LN = 18, N_ = N * (LN + 1) + 1;	/* LN = ceil(log2(N)) */

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

unsigned int X = 12345;

int rand_() {
	return (X *= 3) >> 1;
}

int n;
int pp[N], cc[N];
int *ej[N], eo[N];

void append(int i, int j) {
	int o = eo[i]++;
	if (o >= 2 && (o & o - 1) == 0)
		ej[i] = (int *) realloc(ej[i], o * 2 * sizeof *ej[i]);
	ej[i][o] = j;
}

int xx[N], ta[N], tb[N];

void dfs1(int i) {
	static int time;
	ta[i] = time++;
	xx[i] = 1;
	for (int o = eo[i]; o--; ) {
		int j = ej[i][o];
		dfs1(j);
		xx[i] += xx[j];
	}
	tb[i] = time;
}

int qq[N], yy[N], ii[N], jj[N];

void extend() {
	for (int i = n - 1; i >= 0; i--) {
		yy[i] = qq[i] == -1 ? 0 : xx[qq[i]];
		qq[i] = qq[i] == -1 ? -1 : qq[qq[i]];
	}
}

void sort(int *xx, int *ii, int *jj) {
	memset(kk, 0, (n + 2) * sizeof *kk);
	for (int i = 0; i < n; i++) {
		int j = ii[i];
		kk[xx[j] + 1]++;
	}
	for (int x = 1; x <= n + 1; x++)
		kk[x] += kk[x - 1];
	for (int i = 0; i < n; i++) {
		int j = ii[i];
		jj[kk[xx[j]]++] = j;
	}
}

void compress() {
	for (int i = 0, x = 0; i < n; i++)
		xx[ii[i]] = i + 1 == n || xx[ii[i + 1]] != xx[ii[i]] || yy[ii[i + 1]] != yy[ii[i]] ? x++ : x;
}

int ll[N_], rr[N_], kk_[N_];

int node(int l, int r, int x) {
	static int _ = 1;
	int t_ = _++;
	kk_[t_] = 1;
	if (r - l > 1) {
		int m = (l + r) / 2;
		if (x < m)
			ll[t_] = node(l, m, x);
		else
			rr[t_] = node(m, r, x);
	}
	return t_;
}

int merge(int t1, int t2) {
	if (t1 == 0)
		return t2;
	if (t2 == 0)
		return t1;
	ll[t1] = merge(ll[t1], ll[t2]), rr[t1] = merge(rr[t1], rr[t2]), kk_[t1] += kk_[t2];
	return t1;
}

int query(int t, int l, int r, int k) {
	if (r - l == 1)
		return l;
	int m = (l + r) / 2;
	return k <= kk_[ll[t]] ? query(ll[t], l, m, k) : query(rr[t], m, r, k - kk_[ll[t]]);
}

int ll_[N_], rr_[N_], mn[N_], mx[N_];

int node_(int l, int r, int x) {
	static int _ = 1;
	int t_ = _++;
	mn[t_] = mx[t_] = xx[pp[ii[x]]];
	if (r - l > 1) {
		int m = (l + r) / 2;
		if (x < m)
			ll_[t_] = node_(l, m, x);
		else
			rr_[t_] = node_(m, r, x);
	}
	return t_;
}

int x_, incr;

int merge_(int t1, int t2) {
	if (t1 == 0 && t2 == 0)
		return 0;
	if (t1 == 0) {
		if (x_ > mn[t2])
			incr = 0;
		x_ = mx[t2];
		return t2;
	}
	if (t2 == 0) {
		if (x_ > mn[t1])
			incr = 0;
		x_ = mx[t1];
		return t1;
	}
	ll_[t1] = merge_(ll_[t1], ll_[t2]), rr_[t1] = merge_(rr_[t1], rr_[t2]);
	mn[t1] = min(mn[t1], mn[t2]), mx[t1] = max(mx[t1], mx[t2]);
	return t1;
}

int tt[N], tt_[N], kk[N]; char good[N];

void dfs2(int i) {
	good[i] = 1;
	for (int o = eo[i]; o--; ) {
		int j = ej[i][o];
		dfs2(j);
		if (!good[j])
			good[i] = 0;
	}
	if (!good[i])
		return;
	for (int o = eo[i]; o--; ) {
		int j = ej[i][o];
		jj[cc[j]] = -1;
	}
	for (int o = eo[i]; o--; ) {
		int j = ej[i][o];
		if (jj[cc[j]] != -1) {
			good[i] = 0;
			return;
		}
		jj[cc[j]] = j;
	}
	for (int o = eo[i]; o--; ) {
		int j = ej[i][o];
		tt_[j] = node_(0, n, xx[j]), yy[j] = xx[i], kk[j] = 1;
	}
	tt[i] = node(0, n, xx[i]);
	for (int o = eo[i]; o--; ) {
		int j = ej[i][o];
		tt[i] = merge(tt[i], tt[j]);
		for (int o = eo[j]; o--; ) {
			int k = ej[j][o], j_ = jj[cc[k]];
			if (j_ == -1) {
				good[i] = 0;
				return;
			}
			x_ = -1, incr = 1, tt_[j_] = merge_(tt_[j_], tt_[k]);
			if (!incr) {
				good[i] = 0;
				return;
			}
			yy[j_] = max(yy[j_], yy[k]), kk[j_] += kk[k];
		}
	}
	for (int o = eo[i]; o--; ) {
		int j = ej[i][o];
		if (yy[j] > query(tt[i], 0, n, kk[j])) {
			good[i] = 0;
			return;
		}
	}
}

vi beechtree(int n_, int m, vi pp_, vi cc_) {
	n = n_;
	for (int i = 0; i < n; i++)
		pp[i] = pp_[i], cc[i] = cc_[i] - 1;
	for (int i = 0; i < n; i++)
		ej[i] = (int *) malloc(2 * sizeof *ej[i]);
	for (int i = 1; i < n; i++)
		append(pp[i], i);
	dfs1(0);
	for (int i = 0; i < n; i++) {
		xx[i] = n - xx[i];
		qq[i] = pp[i];
		ii[i] = i;
	}
	for (int l = 0; l <= LN; l++) {
		extend();
		sort(yy, ii, jj);
		sort(xx, jj, ii);
		compress();
	}
	for (int i = 0; i < n; i++)
		yy[i] = ta[i];
	sort(yy, ii, jj);
	sort(xx, jj, ii);
	compress();
	for (int i = 0; i < n; i++)
		jj[i] = -1;
	dfs2(0);
	vi good_(n, 0);
	for (int i = 0; i < n; i++)
		good_[i] = good[i];
	return good_;
}

Compilation message

beechtree.cpp: In function 'void append(int, int)':
beechtree.cpp:26:23: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
   26 |  if (o >= 2 && (o & o - 1) == 0)
      |                     ~~^~~
beechtree.cpp: In function 'void sort(int*, int*, int*)':
beechtree.cpp:55:9: error: 'kk' was not declared in this scope
   55 |  memset(kk, 0, (n + 2) * sizeof *kk);
      |         ^~