제출 #1355743

#제출 시각아이디문제언어결과실행 시간메모리
1355743marcogambaroTree (IOI24_tree)C++20
0 / 100
66 ms101792 KiB
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull long long
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define all(x) x.begin(), x.end()
#define fi first 
#define se second 
#ifdef MARCO
#define infof(str,...) do{ fprintf(stderr, str"\n", ##__VA_ARGS__);} while(0)
#define infor(str,...) do{ fprintf(stderr, str, #__VA_ARGS__);} while(0)
#else 
#define infof(str,...)
#define infor(str,...)
#endif

vector<vector<int>> G;
int N;
vector<int> W;
vector<int> tin, tout;

ll leafw, leafn;

void gett(int v) {
	static int tt = 0;
	tin[v] = tt++;
	for(auto &u: G[v]) {
		gett(u);
	}
	tout[v] = tt;
}

vector<ll> p, sfx;

int dfs(int v) {
	if(G[v].empty()) return 1;

	int k = 0;
	for(auto &u: G[v]) {
		k += dfs(u);
		if(W[v] == 0) {
			p.push_back(k);
			k = 0;
		}
	}

	if(W[v] == 0) return 1;
	else return k;
}

vector<ll> t;
void update(int v, int l, int r, int q, ll x) {
	if(r-l == 1) {
		t[v] = x;
		return;
	}
	int m = (l+r)/2;
	if(q < m) update(v*2, l, m, q, x);
	else update(v*2+1, m, r, q, x);
	t[v] = t[v*2] + t[v*2+1];
}
ll sum(int v, int l, int r, int ql, int qr) {
	if(qr <= l || r <= ql) return 0;
	if(ql <= l && r <= qr) return t[v];
	int m = (l+r)/2;
	return sum(v*2, l, m, ql, qr) + sum(v*2+1, m, r, ql, qr);
} 

vector<ll> ans1;
struct dt1{
	vector<ll> x, d;

	dt1(int k = 1e6+3) {
		x.resize(k*4);
		d.resize(k*4);
		ans1.resize(k);
	}

	void push(int v, int l, int m, int r) {
		x[v*2+1] += x[v];
		d[v*2+1] += d[v];

		x[v*2] += x[v] + d[v]*(m-r);
		d[v*2] += d[v];

		x[v] = 0;
		d[v] = 0;
	}

	void add(int v, int l, int r, int ql, int qr, ll k) {
		if(qr <= l || r <= ql) return;
		if(ql <= l && r <= qr) {
			x[v] += k*(qr-r+1);
			d[v] += k;
			return;
		}

		int m = (l+r)/2;
		add(v*2, l, m, ql, qr, k);
		add(v*2+1, m, r, ql, qr, k);
	}
	void add(int ql, int qr, ll k) {
		add(1, 0, 1e6+3, ql, qr, k);
	}

	void trans(int v, int l, int r) {
		if(r-l == 1) {
			ans1[l] = x[v];
			return;
		}
		int m = (l+r)/2;
		push(v, l, m, r);
		trans(v*2, l, m);
		trans(v*2+1, m, r);
	}
	void trans() {
		trans(1, 0, 1e6+3);
	}
};

struct dt2{
	vector<int> t, lazy;

	dt2() {
		t.resize(N*4, -1);
		lazy.resize(N*4, -1);
	}

	void update(int v, int l, int r, int ql, int qr, int p) {
		if(qr <= l || r <= ql) return;
		if(ql <= l && r <= qr) {
			t[v] = p;
			lazy[v] = p;
			return;
		}

		int m = (l+r)/2;
		if(lazy[v] != -1) {
			for(int u = v*2; u < v*2+2; u++) {
				lazy[u] = t[u] = lazy[v];
			}
			lazy[v] = -1;
		}
		update(v*2, l, m, ql, qr, p);
		update(v*2+1, l, r, ql, qr, p);
	}

	int get(int v, int l, int r, int q) {
		if(r-l == 1) return t[v];
		int m = (l+r)/2;
		if(lazy[v] != -1) {
			for(int u = v*2; u < v*2+2; u++) {
				lazy[u] = t[u] = lazy[v];
			}
			lazy[v] = -1;
		}
		if(q < m) return get(v*2, l, m, q);
		return get(v*2+1, m, r, q);
	}
	int get(int q) {
		return get(1, 0, N, q);
	}
};

void init(std::vector<int> P, std::vector<int> W) {
	N = P.size();
	
	G.resize(N);	
	t.resize(N*4);

	for(int i=1; i<N; i++) {
		G[P[i]].emplace_back(i);
	}
	tin = tout = vector<int>(N);
	gett(0);
	
	vector<int> V;
	for(int i=0; i<N; i++) {
		if(G[i].empty()) {
			leafw+=W[i];
		 	leafn++;
			update(1, 0, N, tin[i], 1);
		}
		else V.push_back(i);
	}

	sort(all(V), [&](int &i, int &j){return W[i] < W[j];});
	dt1 sgans;
	dt2 hh;

	int solved = leafn;

	for(auto &v: V) {
		int p = hh.get(tin[v]);
		int sub = sum(1, 0, N, tin[v], tout[v]);

		if(p == -1) {
			// move solved by sub-1!
			sgans.add(0, solved, W[v]);
			sgans.add(0, solved-sub+1, -W[v]);

			solved -= sub-1;
			hh.update(1, 0, N, tin[v], tout[v], v);
			update(1, 0, N, tin[v], -sub+1);
		}
		else {
			// recover p by stealing the size of sub
			sgans.add(0, sub, W[v]-W[p]);

			hh.update(1, 0, N, tin[v], tout[v], v);
			update(1, 0, N, tin[v], -sub+1);
			update(1, 0, N, tin[p], +sub-1);
		}
	}

	sgans.trans();
	::W.swap(W);
}

long long query(int L, int R) {
	return ans1[R] + leafw; 
}


#ifdef MARCO
int main() {
  int N;
  assert(1 == scanf("%d", &N));
  std::vector<int> P(N);
  P[0] = -1;
  for (int i = 1; i < N; i++)
    assert(1 == scanf("%d", &P[i]));
  std::vector<int> W(N);
  for (int i = 0; i < N; i++)
    assert(1 == scanf("%d", &W[i]));
  int Q;
  assert(1 == scanf("%d", &Q));
  std::vector<int> L(Q), R(Q);
  for (int j = 0; j < Q; j++)
    assert(2 == scanf("%d%d", &L[j], &R[j]));
  fclose(stdin);


  init(P, W);
  std::vector<long long> A(Q);
  for (int j = 0; j < Q; j++)
    A[j] = query(L[j], R[j]);

  for (int j = 0; j < Q; j++)
    printf("%lld\n", A[j]);
  fclose(stdout);

  return 0;
}
#endif
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...