Submission #297617

#TimeUsernameProblemLanguageResultExecution timeMemory
297617limabeansElection Campaign (JOI15_election_campaign)C++17
30 / 100
1057 ms155128 KiB
#include <bits/stdc++.h> using namespace std; template<typename T> void out(T x) { cout << x << endl; exit(0); } #define watch(x) cout << (#x) << " is " << (x) << endl using ll = long long; const ll mod = 1e9+7; const int maxn = 1e6 + 5; const int LOG = 20; const ll inf = 1e18; struct MaxLazySegmentTree { vector<ll> t, o; void init(int n) { n += 10; t.resize(4*n); o.resize(4*n); } void push(int v) { t[2*v]+=o[v]; t[2*v+1]+=o[v]; o[2*v]+=o[v]; o[2*v+1]+=o[v]; o[v]=0; } ll queryMax(int v, int tl, int tr, int l, int r) { if (l>tr||r<tl) return -inf; if (l<=tl&&tr<=r) { return t[v]; } else { push(v); int tm=(tl+tr)/2; return max(queryMax(2*v,tl,tm,l,r),queryMax(2*v+1,tm+1,tr,l,r)); } } void rangeAdd(int v, int tl, int tr, int l, int r, ll dx) { if (l>r) return; if (l>tr||r<tl) return; if (l<=tl&&tr<=r) { t[v]+=dx; o[v]+=dx; } else { push(v); int tm=(tl+tr)/2; rangeAdd(2*v,tl,tm,l,r,dx); rangeAdd(2*v+1,tm+1,tr,l,r,dx); t[v]=max(t[2*v],t[2*v+1]); } } }; vector<int> ev[maxn]; int n, m; vector<int> g[maxn]; int dep[maxn]; int par[maxn][LOG+1]; vector<int> leaves[maxn]; ll dp0[maxn]; // no path goes direct thru me ll dp1[maxn]; // path goes directly thru me vector<ll> dp[maxn]; // no path thru me, and no path thru ith leaf void gen(int at, int p) { for (int j=1; j<LOG; j++) { par[at][j] = par[par[at][j-1]][j-1]; } for (int to: g[at]) { if (to==p) continue; leaves[at].push_back(to); par[to][0]=at; dep[to]=1+dep[at]; gen(to,at); } } int lca(int x, int y) { if (dep[x]<dep[y]) swap(x,y); int dx=dep[x]-dep[y]; for (int j=0; j<LOG; j++) { if (dx>>j&1) { x=par[x][j]; } } if (x==y) return x; for (int j=LOG-1; j>=0; j--) { if (par[x][j] != par[y][j]) { x=par[x][j]; y=par[y][j]; } } return par[x][0]; } int a[maxn], b[maxn]; ll c[maxn]; vector<int> qu[maxn]; void procQuery(int i) { int from = a[i]; int to = b[i]; int mid = lca(from, to); qu[mid].push_back(i); } void dfs(int at) { vector<ll> pre; for (int to: leaves[at]) { dfs(to); ll tmp = max(dp0[to], dp1[to]); pre.push_back(tmp); dp0[at] += tmp; } int lcount = leaves[at].size(); for (int i=1; i<lcount; i++) { pre[i] += pre[i-1]; } auto qry = [&](int l, int r) { if (l>r) return 0ll; return pre[r] - (l>0 ? pre[l-1] : 0ll); }; dp[at].resize(lcount); // ith leaf is banned for (int i=0; i<lcount; i++) { dp[at][i] = qry(0,i-1) + qry(i+1, lcount-1); } for (int qi: qu[at]) { vector<vector<int>> paths; // get paths a->at and at<-b for (int nd: {a[qi],b[qi]}) { if (nd==at) continue; vector<int> path = {nd}; while (par[nd][0] != at) { nd=par[nd][0]; path.push_back(nd); } reverse(path.begin(), path.end()); paths.push_back(path); } ll cur = c[qi]; assert(int(paths.size()) <= 2); for (int to: leaves[at]) { int id=-1; for (int j=0; j<int(paths.size()); j++) { if (paths[j].front() == to) { id = j; } } // at->to->...a if (~id) { auto &p = paths[id]; int plen = p.size(); for (int j=0; j<plen; j++) { if (j==plen-1) { int end = p[j]; cur += dp0[end]; } else { int nid=0; while (leaves[p[j]][nid] != p[j+1]) nid++; cur += dp[p[j]][nid]; } } } else { cur += max(dp0[to],dp1[to]); } } dp1[at] = max(dp1[at], cur); } } ll solveTask23() { //cerr<<"solveTask23"<<endl; MaxLazySegmentTree dp; dp.init(n+10); auto qry = [&](int i) { if (i==0) return 0ll; return dp.queryMax(1,1,n,1,i); }; auto upd = [&](int i, ll val) { ll cur = dp.queryMax(1,1,n,i,i); if (val <= cur) return; ll dx = val-cur; dp.rangeAdd(1,1,n,i,i,dx); }; for (int i=1; i<=n; i++) { for (int idx: ev[i]) { int l = a[idx]; int r = b[idx]; int val = c[idx]; upd(r, val+qry(l-1)); } } return qry(n); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; bool line = true; for (int i=1; i<=n-1; i++) { int u,v; cin>>u>>v; line &= (u==i && v==i+1); --u; --v; g[u].push_back(v); g[v].push_back(u); } gen(0,0); cin>>m; for (int i=0; i<m; i++) { cin>>a[i]>>b[i]>>c[i]; if (line) { ev[b[i]].push_back(i); if (a[i]>b[i]) swap(a[i],b[i]); } else { --a[i]; --b[i]; } procQuery(i); } if (line) { out(solveTask23()); } dfs(0); ll res = max(dp0[0], dp1[0]); cout<<res<<endl; return 0; }
#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...