Submission #520859

#TimeUsernameProblemLanguageResultExecution timeMemory
520859ymmElection Campaign (JOI15_election_campaign)C++17
100 / 100
198 ms66860 KiB
///
///   Oh? You're approaching me?
///

#include <bits/stdc++.h>
#define Loop(x,l,r) for(ll x = ll(l); x < ll(r); ++x)
#define LoopR(x,l,r) for(ll x = ll(r)-1; x >= ll(l); --x)
#define Kill(x) exit((cout << (x) << '\n', 0))
typedef long long ll;
typedef std::pair<int,int> pii;
typedef std::pair<ll,ll> pll;
using namespace std;

const int N = 100010;
vector<int> A[N];
int st[N], ft[N], rt[N];
vector<pair<int,pii>> C[N];
int n, m;

namespace rmq
{
	const int lg = 20;
	vector<pii> vec;
	pii a[lg][2*N];
	int n;

	void init(){
		n = vec.size();
		Loop(i,0,n) a[0][i] = vec[i];
		Loop(k,0,lg-1) for(int i=0; i+(2<<k)<=n; ++i)
			a[k+1][i] = min(a[k][i], a[k][i+(1<<k)]);
	}

	pii get(int l, int r){
		int k = __lg(r-l);
		return min(a[k][l], a[k][r-(1<<k)]);
	}
}

void dfs1(int v, int p, int h, int& t){
	st[v] = t++;
	rt[v] = rmq::vec.size();
	rmq::vec.emplace_back(h, v);
	for(int u : A[v])
		if(u != p)
			dfs1(u, v, h+1, t),
			rmq::vec.emplace_back(h, v);
	ft[v] = t;
}

mt19937 rd(time(0));
struct node
{
	node *l=0, *r=0;
	int key, val, lzy=0;
	int pri=rd();
	node(int x, int y){key=x;val=y;}
};

void ppg(node* t){
	if(t->lzy){
		t->val += t->lzy;
		if(t->l) t->l->lzy += t->lzy;
		if(t->r) t->r->lzy += t->lzy;
		t->lzy = 0;
	}
}

int get(node* t, int k){
	assert(t);
	ppg(t);
	if(k < t->key) return get(t->l, k);
	if(k > t->key) return get(t->r, k);
	return t->val;
}

node* merge(node* t, node* u){
	if(!t) return u;
	if(!u) return t;
	if(t->pri > u->pri){
		ppg(t);
		t->r = merge(t->r, u);
		return t;
	} else {
		ppg(u);
		u->l = merge(t, u->l);
		return u;
	}
}

pair<int,node*> dfs2(int v, int p){
	vector<int> st, cv;
	vector<node*> ct;
	int csum=0;
	for(int u : A[v]){
		if(u==p) continue;
		st.push_back(::st[u]);
		auto [x, y] = dfs2(u, v);
		csum += x;
		cv.push_back(x);
		ct.push_back(y);
	}
	int ans = csum;
	for(auto [w, pr] : C[v]){
		auto [a, b] = pr;
		int ca = upper_bound(st.begin(), st.end(), ::st[a])-st.begin()-1;
		int cb = upper_bound(st.begin(), st.end(), ::st[b])-st.begin()-1;
		int val = csum + w;
		if(ca>=0) val += get(ct[ca], ::st[a])-cv[ca];
		if(cb>=0) val += get(ct[cb], ::st[b])-cv[cb];
		ans = max(ans, val);
	}
	node* t = new node(::st[v], csum);
	Loop(i,0,ct.size()){
		ct[i]->lzy += csum-cv[i];
		t = merge(t, ct[i]);
	}
	return {ans, t};
}

int main()
{
	cin.tie(0) -> sync_with_stdio(false);
	cin >> n;
	Loop(i,1,n){
		int v, u;
		cin >> v >> u;
		--v; --u;
		A[v].push_back(u);
		A[u].push_back(v);
	}
	dfs1(0, -1, 0, *new int(0));
	rmq::init();
	cin >> m;
	Loop(i,0,m){
		int a, b, x;
		cin >> a >> b >> x;
		--a; --b;
		if(rt[a] > rt[b]) swap(a, b);
		int lca = rmq::get(rt[a], rt[b]+1).second;
		C[lca].push_back({x, {a, b}});
	}
	cout << dfs2(0, -1).first << '\n';
}
#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...