Submission #883114

#TimeUsernameProblemLanguageResultExecution timeMemory
883114amunduzbaevTruck Driver (IOI23_deliveries)C++17
29 / 100
1087 ms49740 KiB
#include "deliveries.h"
 
#include "bits/stdc++.h"
using namespace std;
 
#define ar array
typedef long long ll;
//~ #define int ll
 
const int N = 1e5 + 5;
int n, cur;
ll tot;
vector<vector<ar<int, 2>>> edges;
vector<int> w;
vector<ar<int, 2>> par;
vector<ll> sub;
 
struct ST{
	ll Max[N << 2], sum[N << 2], f[N << 2], b[N << 2];
	
	void set(int i, int v, int lx, int rx, int x){
		if(lx == rx) { 
			b[x] = v; return;
		}
		
		int m = (lx + rx) >> 1;
		if(i <= m) set(i, v, lx, m, x << 1);
		else set(i, v, m + 1, rx, x << 1 | 1);
		
		b[x] = b[x << 1] + b[x << 1 | 1];
	} void set(int i, int v) { set(i, v, 0, N, 1); }
	
	void push(int x, int lx, int rx){
		if(lx == rx) return;
		Max[x << 1] += f[x], Max[x << 1 | 1] += f[x];
		sum[x << 1] += b[x << 1] * f[x];
		sum[x << 1 | 1] += b[x << 1 | 1] * f[x];
		f[x << 1] += f[x], f[x << 1 | 1] += f[x];
		
		f[x] = 0;
	}
	
	void add(int l, int r, int v, int lx, int rx, int x){
		if(lx > r || rx < l) return;
		if(lx >= l && rx <= r){
			Max[x] += v;
			sum[x] += b[x] * v;
			f[x] += v;
			return;
		}
		
		int m = (lx + rx) >> 1;
		push(x, lx, rx);
		add(l, r, v, lx, m, x << 1);
		add(l, r, v, m + 1, rx, x << 1 | 1);
		
		Max[x] = max(Max[x << 1], Max[x << 1 | 1]);
		sum[x] = sum[x << 1] + sum[x << 1 | 1];
	} void add(int l, int r, int v) { add(l, r, v, 0, N, 1); }
	
	ll get(int l, int r, int lx, int rx, int x){
		if(lx > r || rx < l) return 0ll;
		if(lx >= l && rx <= r) return sum[x];
		
		int m = (lx + rx) >> 1;
		push(x, lx, rx);
		
		return get(l, r, lx, m, x << 1) + get(l, r, m + 1, rx, x << 1 | 1);
	} ll get(int l, int r) { return get(l, r, 0, N, 1) ; }
	
	ll get_(int l, int r, int lx, int rx, int x){
		if(lx > r || rx < l ) return 0ll;
		if(lx >= l && rx <= r) return Max[x];
		
		int m = (lx + rx) >> 1;
		push(x, lx, rx);
		
		return max(get_(l, r, lx, m, x << 1), get_(l, r, m + 1, rx, x << 1 | 1));
	} ll get_(int l, int r) { return get_(l, r, 0, N, 1); }
	
	int big(int v, int lx, int rx, int x){
		if(lx == rx) return lx;
		
		int m = (lx + rx) >> 1;
		push(x, lx, rx);
		
		if(Max[x << 1 | 1] >= v) return big(v, m + 1, rx, x << 1 | 1);
		else return big(v, lx, m, x << 1);
	}
	
	int big(int v) { return big(v, 0, N, 1); }
}tree;
 
vector<int> cnt, hev, head, pos, ver;
vector<ll> pref;
 
void init(int N, vector<int> u, vector<int> v, vector<int> t, vector<int> W) {
	w = W; n = N;
	edges.resize(n);
	sub.resize(n);
	par.resize(n);
	cnt.resize(n), hev.resize(n);
	head.resize(n), pos.resize(n), ver.resize(n);
	pref.resize(n);
	
	tot = 2;
	for(int i=0;i<n;i++) tot += w[i];
	
	for(int i=0;i + 1<n;i++){
		edges[u[i]].push_back({v[i], 2 * t[i]});
		edges[v[i]].push_back({u[i], 2 * t[i]});
	}
	
	function<void(int, int)> dfs = [&](int u, int p){
		sub[u] = w[u] + (u == 0) * 2;
		cnt[u] = 1, hev[u] = -1;
		
		for(auto [x, c] : edges[u]){
			if(x == p) continue;
			par[x] = {u, c};
			pref[x] = pref[u] + c;
			
			dfs(x, u);
			if(hev[u] == -1 || cnt[x] > cnt[hev[u]]) hev[u] = x;
			
			cnt[u] += cnt[x];
			sub[u] += sub[x];
		}
	};
	
	dfs(0, 0);
	
	int last = 0;
	function<void(int, int, int)> dec = [&](int u, int p, int P){
		pos[u] = last++, ver[pos[u]] = u, head[u] = P;
		if(~hev[u]){
			dec(hev[u], u, P);
		}
		
		for(auto [x, c] : edges[u]){
			if(x == p || x == hev[u]) continue;
			dec(x, u, x);
		}
	};
	
	dec(0, 0, 0);
	for(int i=0;i<n;i++){
		tree.set(pos[i], par[i][1]);
	}
	for(int i=0;i<n;i++){
		tree.add(pos[i], pos[i], sub[i]);
	}
	
	//~ for(int i=0;i<n;i++){
		//~ cout<<sub[i]<<" ";
	//~ } cout<<endl;
	//~ for(int i=0;i<n;i++){
		//~ cout<<par[i][1]<<" ";
	//~ } cout<<endl;
	//~ for(int i=0;i<n;i++){
		//~ cout<<tree.get(pos[i], pos[i])<<" ";
	//~ } cout<<endl;
	//~ for(int i=0;i<n;i++){
		//~ cout<<tree.get_(pos[i], pos[i])<<" ";
	//~ }
	//~ cout<<endl;
}
 
ll get(int u){
	ll res = 0;
	while(head[u]){
		res += tree.get(pos[head[u]], pos[u]);
		u = par[head[u]][0];
	}
	
	res += tree.get(pos[head[u]], pos[u]);
	return res;
}
 
void add(int u, int x){
	while(head[u]){
		tree.add(pos[head[u]], pos[u], x);
		u = par[head[u]][0];
	}
	
	tree.add(pos[head[u]], pos[u], x);
}
 
ll max_time(int s, int x) {
	x = -w[s] + x;
	tot += x;
	w[s] += x;
	
	add(s, x);
	
	//~ cout<<tot<<" "<<(tot + 1) / 2<<"\n";
	//~ for(int i=0;i<n;i++){
		//~ cout<<tree.get_(i, i)<<" ";
	//~ } cout<<"\n";
	
	//~ cout<<tree.Max[1]<<endl;
	//~ cout<<(tot + 1) / 2<<endl;
	//~ cout<<tree.big((tot + 1) / 2)<<endl;;
	
	int cen = ver[tree.big((tot + 1) / 2)];
	
	//~ cout<<cen<<" "<<tree.sum[1]<<" "<<(tot - 1) * pref[cen]<<" "<<get(cen)<<"\n";
	
	ll res = tree.sum[1] + (tot - 1) * pref[cen];
	res -= get(cen) * 2;
	
	return res;
}
#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...