제출 #1355237

#제출 시각아이디문제언어결과실행 시간메모리
1355237marcogambaro트리 (IOI24_tree)C++20
41 / 100
2098 ms68356 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;
vector<set<pii>> st;

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

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

	for(int i=1; i<N; i++) {
		G[P[i]].emplace_back(i);
	}
	
	tin = tout = vector<int>(N);
	gett(0);
	st.resize(N);
}

ll ans;
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);
}

/*
8
0 1 2 3 3 2 1
1 1 2 1 1 1 1 1
1
2 3
*/


void dfs(int v, ll L, ll R) {
	for(auto &u: G[v])
		dfs(u, L, R);
		
	if(G[v].size() == 0) {
		ans += L*W[v];
		update(1, 0, N, tin[v], L);
		return;
	}

	int bigc = -1;
	for(auto &u: G[v]) {
		auto it = st[u].end();
		while(it != st[u].begin()) {
			it--;
			if(it->fi >= W[v]) {
				it = st[u].erase(it);
			}
			else break;
		}

		if(bigc == -1 || st[u].size() > st[bigc].size()) bigc = u;
	}

	st[bigc].swap(st[v]);
	for(auto &u: G[v]) {
		if(u != bigc) {
			for(auto &p: st[u])
				st[v].insert(p);
		}
	}
	st[v].insert({W[v], v});

	auto it = st[v].begin();
	ll K = sum(1, 0, N, tin[v], tout[v]);

	while(K > R) {
		assert(!st[v].empty());
		auto &[w, u] = *it;
		ll ku = sum(1, 0, N, tin[u], tout[u]);

		ll red = min(K-R, ku-L);
		if(red == 0){
			it = st[v].erase(it);
			continue;
		}

		K -= red;
		ans += w*red;
		update(1, 0, N, tin[u], -red);
	}
	return;
}


long long query(int L, int R) {
	ans = 0;
	st = vector<set<pii>>(N);
	t = vector<ll>(4*N);
	dfs(0, L, R);
	return ans;
}


#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...