Submission #230054

#TimeUsernameProblemLanguageResultExecution timeMemory
230054liwiElection Campaign (JOI15_election_campaign)C++14
100 / 100
793 ms72696 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; #define scan(x) do{while((x=getchar())<'0'); for(x-='0'; '0'<=(_=getchar()); x=(x<<3)+(x<<1)+_-'0');}while(0) char _; #define complete_unique(a) a.erase(unique(a.begin(),a.end()),a.end()) #define all(a) a.begin(),a.end() #define println printf("\n"); #define readln(x) getline(cin,x); #define pb push_back #define endl "\n" #define INT_INF 0x3f3f3f3f #define LL_INF 0x3f3f3f3f3f3f3f3f #define EPS 1e-9 #define MOD 1000000007 #define MOD2 1494318097 #define SEED 131 #define mp make_pair #define fastio cin.tie(0); cin.sync_with_stdio(0); #define MAXN 100005 typedef unsigned long long ull; typedef long long ll; typedef long double ld; typedef pair<int,int> pii; typedef pair<double,double> pdd; typedef pair<ll,ll> pll; typedef pair<int,pii> triple; typedef int8_t byte; const ld PI = (ld)4*atanl(1); mt19937 g1(chrono::steady_clock::now().time_since_epoch().count()); int randint(int a, int b){return uniform_int_distribution<int>(a, b)(g1);} ll randlong(ll a,ll b){return uniform_int_distribution<long long>(a, b)(g1);} ll gcd(ll a, ll b){return b == 0 ? a : gcd(b, a % b);} ll lcm(ll a, ll b){return a*b/gcd(a,b);} ll fpow(ll b, ll exp, ll mod){if(exp == 0) return 1;ll t = fpow(b,exp/2,mod);if(exp&1) return t*t%mod*b%mod;return t*t%mod;} ll divmod(ll i, ll j, ll mod){i%=mod,j%=mod;return i*fpow(j,mod-2,mod)%mod;} template<typename T> struct node{ int l,r; T mx,mn,sum,lazy; }; template<typename T> struct HLDSegTree{ node<T> seg[4*MAXN]; inline ll sz(int rt){return seg[rt].r-seg[rt].l+1;} inline void push_up(int rt){ seg[rt].mx = max(seg[rt<<1].mx,seg[rt<<1|1].mx); seg[rt].mn = min(seg[rt<<1].mn,seg[rt<<1|1].mn); seg[rt].sum = seg[rt<<1].sum+seg[rt<<1|1].sum; } inline void push_down(int rt){ seg[rt<<1].mx+=seg[rt].lazy, seg[rt<<1|1].mx+=seg[rt].lazy; seg[rt<<1].mn+=seg[rt].lazy, seg[rt<<1|1].mn+=seg[rt].lazy; seg[rt<<1].sum+=seg[rt].lazy*sz(rt<<1), seg[rt<<1|1].sum+=seg[rt].lazy*sz(rt<<1|1); seg[rt<<1].lazy+=seg[rt].lazy, seg[rt<<1|1].lazy+=seg[rt].lazy; seg[rt].lazy = 0; } void build(int l, int r, int rt){ seg[rt].l = l, seg[rt].r = r, seg[rt].sum = seg[rt].lazy = 0, seg[rt].mn = INT_INF, seg[rt].mx = -INT_INF; if(l == r) return; int mid = (l+r)/2; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); } void update(int l, int r, int rt, T val){ if(l > r) return; if(seg[rt].l == l && seg[rt].r == r){ seg[rt].mx+=val, seg[rt].mn+=val, seg[rt].lazy+=val; seg[rt].sum+=val*sz(rt); return; } if(seg[rt].lazy) push_down(rt); int mid = (seg[rt].l+seg[rt].r)/2; if(r <= mid) update(l,r,rt<<1,val); else if(l > mid) update(l,r,rt<<1|1,val); else update(l,mid,rt<<1,val), update(mid+1,r,rt<<1|1,val); push_up(rt); } T query(int l, int r, int rt){ if(seg[rt].l == l && seg[rt].r == r) return seg[rt].sum; if(seg[rt].lazy) push_down(rt); int mid = (seg[rt].l+seg[rt].r)/2; if(r <= mid) return query(l,r,rt<<1); else if(l > mid) return query(l,r,rt<<1|1); return query(l,mid,rt<<1)+query(mid+1,r,rt<<1|1); } }; template<typename T> struct HLD{ int sz[MAXN],heavy[MAXN],par[MAXN],head[MAXN],depth[MAXN],pos[MAXN],cnt=0; HLDSegTree<T> seg; vector<pair<int,ll>> connections[MAXN]; vector<pair<pii,int>> paths[MAXN]; inline void add_edge(int a, int b, ll val = 0){ connections[a].pb(mp(b,val)); connections[b].pb(mp(a,val)); } int dfs(int node, int prev){ sz[node] = 1; for(pair<int,ll> check:connections[node]){ if(check.first == prev) continue; par[check.first] = node, depth[check.first] = depth[node]+1; int tmp = dfs(check.first,node); if(tmp > sz[heavy[node]]) heavy[node] = check.first; sz[node]+=tmp; } return sz[node]; } void decompose(int node, int prev, int hh){ head[node] = hh, pos[node] = ++cnt; if(heavy[node]) decompose(heavy[node],node,hh); for(pair<int,ll> check:connections[node]){ if(check.first == prev || check.first == heavy[node]) continue; decompose(check.first,node,check.first); } } inline void init(){ memset(heavy,0,sizeof heavy); memset(head,0,sizeof head); memset(depth,0,sizeof depth); memset(par,0,sizeof par); dfs(1,-1); decompose(1,-1,1); seg.build(1,cnt,1); } inline int lca(int a, int b){ for(; head[a] != head[b]; b = par[head[b]]) if(depth[head[a]] > depth[head[b]]) swap(a,b); if(depth[a] > depth[b]) swap(a,b); return a; } inline void update(int a, int b, T v){ for(; head[a] != head[b]; b = par[head[b]]){ if(depth[head[a]] > depth[head[b]]) swap(a,b); seg.update(pos[head[b]],pos[b],1,v); } if(depth[a] > depth[b]) swap(a,b); seg.update(pos[a],pos[b],1,v); } inline T query(int a, int b){ T res = 0; for(; head[a] != head[b]; b = par[head[b]]){ if(depth[head[a]] > depth[head[b]]) swap(a,b); res+=seg.query(pos[head[b]],pos[b],1); } if(depth[a] > depth[b]) swap(a,b); return res+seg.query(pos[a],pos[b],1); } }; int N,M; ll dp[MAXN],ch_sum[MAXN]; HLD<ll> hld,d; void solve(int node, int prev){ for(auto check:hld.connections[node]){ if(check.first == prev) continue; solve(check.first,node); ch_sum[node]+=dp[check.first]; } dp[node] = ch_sum[node]; hld.update(node,node,ch_sum[node]); for(pair<pii,int> check:hld.paths[node]){ ll val = hld.query(check.first.first,check.first.second)-d.query(check.first.first,check.first.second)+check.second; dp[node] = max(dp[node],val); } d.update(node,node,dp[node]); } int main(){ fastio; cin >> N; for(int i=1; i<N; i++){ int a,b; cin >> a >> b; hld.add_edge(a,b); d.add_edge(a,b); } hld.init(); d.init(); cin >> M; for(int i=1; i<=M; i++){ int a,b,c; cin >> a >> b >> c; hld.paths[hld.lca(a,b)].pb(mp(mp(a,b),c)); } solve(1,-1); cout << dp[1] << endl; }
#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...