Submission #112737

#TimeUsernameProblemLanguageResultExecution timeMemory
112737YehezkielElection Campaign (JOI15_election_campaign)C++11
100 / 100
302 ms38520 KiB
//#include "campaign.h" #include <bits/stdc++.h> using namespace std; #define psb push_back #define fi first #define se second #define eb emplace_back typedef pair<int,int> PII; const int MAXN = 100000; int n, m; vector <int> node[MAXN + 5]; void moveToGlobal(int N, int M, const vector <int> &U, const vector <int> &V) { n = N; m = M; for (int i = 0; i < n - 1; ++i) { node[U[i]].psb(V[i]); node[V[i]].psb(U[i]); } } const int logN = 17; int par[logN + 5][MAXN + 5] = {}; int depth[MAXN + 5]; void setUpLCA(int now, int _par = 0, int _depth = 0) { par[0][now] = _par; depth[now] = _depth; for (auto v: node[now]) { if (v == par[0][now]) { continue; } setUpLCA(v, now, _depth + 1); } } void setUpLCA() { setUpLCA(1); for (int i = 1; i < logN; ++i) { for (int j = 1; j <= n; ++j) { par[i][j] = par[i - 1][par[i - 1][j]]; } } } int LCA(int u, int v) { if (depth[u] > depth[v]) swap(u, v); int diff = depth[v] - depth[u]; for (int i = 0; i < logN; ++i) { if (diff & (1 << i)) v = par[i][v]; } assert(depth[u] == depth[v]); if (u == v) return u; for (int i = logN - 1; i >= 0; --i) { if (par[i][u] == par[i][v]) continue; u = par[i][u], v = par[i][v]; } assert(par[0][u] == par[0][v]); return par[0][u]; } class treeNode { public: int fi, se; int fiLazy, seLazy; bool lazy; treeNode() { fi = se = fiLazy = seLazy = 0; lazy = false; } treeNode operator + (const treeNode &other) { treeNode ret; ret.fi = fi + other.fi; ret.se = se + other.se; return ret; } void apply(int newFi, int newSe) { fiLazy += newFi; fi += newFi; seLazy += newSe; se += newSe; lazy = true; } PII toPair() { return make_pair(fi, se); } }; class Segtree { public: static const int treeSize = 131072; treeNode tree[treeSize * 2 + 5]; void pushDown(int idx) { if (!tree[idx].lazy) return; tree[idx << 1].apply(tree[idx].fiLazy, tree[idx].seLazy); tree[(idx << 1) | 1].apply(tree[idx].fiLazy, tree[idx].seLazy); tree[idx].fiLazy = tree[idx].seLazy = 0; tree[idx].lazy = false; } void pullUp(int idx) { tree[idx] = tree[idx << 1] + tree[(idx << 1) | 1]; } int l, r, newFi, newSe; void update(int left, int right, int idx) { if (l <= left && right <= r) { tree[idx].apply(newFi, newSe); return; } if (l > right || r < left) { return; } pushDown(idx); int mid = (left + right) >> 1; update(left, mid, idx << 1); update(mid + 1, right, (idx << 1) | 1); pullUp(idx); } void update(int _l, int _r, int _newFi, int _newSe) { l = _l; r = _r; newFi = _newFi; newSe = _newSe; update(1, n, 1); } PII combine(PII a, PII b) { return make_pair(a.fi + b.fi, a.se + b.se); } int target; PII query(int left, int right, int idx) { if (left == right) { assert(left == target); return tree[idx].toPair(); } pushDown(idx); int mid = (left + right) >> 1; if (target <= mid) return query(left, mid, idx << 1); else return query(mid + 1, right, (idx << 1) | 1); } PII query(int _target) { target = _target; return query(1, n, 1); } }segtree; class query{ public: int u, v, val; query(int _u, int _v, int _val) : u(_u), v(_v), val(_val) {} }; vector <query> queries[MAXN + 5]; void fillQueries(const vector <int> &A, const vector <int> &B, const vector <int> &C) { for (int i = 0; i < m; ++i) { int temp = LCA(A[i], B[i]); queries[temp].eb(A[i], B[i], C[i]); } } int rangeL[MAXN + 5]; int rangeR[MAXN + 5]; int counter = 0; void fillRange(int now) { rangeL[now] = ++counter; for (auto v: node[now]) { if (v == par[0][now]) continue; fillRange(v); } rangeR[now] = counter; } void fillRange() { fillRange(1); } int dp[2][MAXN + 5] = {}; int findOptimum(int sub, int root) { assert(sub != root); assert(depth[sub] > depth[root]); PII temp = segtree.query(rangeL[sub]); return temp.se - temp.fi + dp[1][root]; } void fillDp(int now) { dp[0][now] = dp[1][now] = 0; for (auto v: node[now]) { if (v == par[0][now]) { continue; } fillDp(v); dp[1][now] += dp[0][v]; } for (auto q: queries[now]) { if (now == q.v) swap(q.u, q.v); int candidate = q.val; if (q.u == now) { candidate += findOptimum(q.v, now); } else { candidate += findOptimum(q.u, now); candidate += findOptimum(q.v, now); candidate -= dp[1][now]; } dp[0][now] = max(dp[0][now], candidate); } dp[0][now] = max(dp[0][now], dp[1][now]); segtree.update(rangeL[now], rangeR[now], dp[0][now], dp[1][now]); } void fillDp() { fillDp(1); } int getMaximumVotes(int N, int M, vector<int> U, vector<int> V, vector<int> A, vector<int> B, vector<int> C) { moveToGlobal(N, M, U, V); setUpLCA(); fillQueries(A, B, C); fillRange(); fillDp(); return dp[0][1]; } int main() { int N, M; vector<int> U, V; vector<int> A, B, C; scanf("%d", &N); U.resize(N-1); V.resize(N-1); for (int i = 0 ; i < N-1 ; i++) { scanf("%d %d", &U[i], &V[i]); } scanf("%d", &M); A.resize(M); B.resize(M); C.resize(M); for (int i = 0 ; i < M ; i++) { scanf("%d %d %d", &A[i], &B[i], &C[i]); } int ans = getMaximumVotes(N, M, U, V, A, B, C); printf("%d\n", ans); return 0; }

Compilation message (stderr)

election_campaign.cpp: In function 'int main()':
election_campaign.cpp:251:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &N);
   ~~~~~^~~~~~~~~~
election_campaign.cpp:255:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d %d", &U[i], &V[i]);
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
election_campaign.cpp:258:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &M);
   ~~~~~^~~~~~~~~~
election_campaign.cpp:261:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d %d %d", &A[i], &B[i], &C[i]);
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...