Submission #743074

#TimeUsernameProblemLanguageResultExecution timeMemory
743074flappybirdDesignated Cities (JOI19_designated_cities)C++17
23 / 100
2061 ms56672 KiB
#include <bits/stdc++.h> #pragma GCC optimize("O3") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC target("avx,avx2,fma") using namespace std; typedef long long ll; typedef pair<ll, ll> pll; typedef pair<int, int> pii; #define MAX 201010 #define MAXS 20 #define INF 1000000000000000001 #define bb ' ' #define ln '\n' #define Ln '\n' ll dep[MAX]; ll segv[MAX]; typedef pair<ll, int> pli; namespace segtree { pli tree[MAX * 4]; ll lazy[MAX * 4]; void init(int s, int e, int loc = 1) { if (s == e) { tree[loc].first = segv[s]; tree[loc].second = s; return; } int m = s + e >> 1; lazy[loc] = 0; init(s, m, loc * 2); init(m + 1, e, loc * 2 + 1); tree[loc] = max(tree[loc * 2], tree[loc * 2 + 1]); } void prop(int loc = 1) { for (auto c : { loc * 2, loc * 2 + 1 }) { tree[c].first += lazy[loc]; lazy[c] += lazy[loc]; } lazy[loc] = 0; } void upd(int s, int e, int l, int r, ll v, int loc = 1) { if (e < l || r < s) return; if (s != e) prop(loc); if (l <= s && e <= r) { tree[loc].first += v; lazy[loc] += v; return; } int m = s + e >> 1; upd(s, m, l, r, v, loc * 2); upd(m + 1, e, l, r, v, loc * 2 + 1); tree[loc] = max(tree[loc * 2], tree[loc * 2 + 1]); } pli query(int s, int e, int l, int r, int loc = 1) { if (e < l || r < s) return pli(-1, 0); if (l <= s && e <= r) return tree[loc]; if (s != e) prop(loc); int m = s + e >> 1; return max(query(s, m, l, r, loc * 2), query(m + 1, e, l, r, loc * 2 + 1)); } } vector<int> adj[MAX]; pii edges[MAX]; pii costs[MAX]; int get_next(int x, int e) { return edges[e].first + edges[e].second - x; } int get_cost(int x, int e) { if (x == edges[e].first) return costs[e].first; if (x == edges[e].second) return costs[e].second; } int vis[MAX]; int num[MAX]; ll ans[MAX]; void get_num(int x, int p = 0) { num[x] = 1; for (auto e : adj[x]) { int v = get_next(x, e); if (vis[v]) continue; if (v == p) continue; get_num(v, x); num[x] += num[v]; } } int grp[MAX]; int prt[MAX]; pii range[MAX]; int rev[MAX]; int cnt; ll sump[MAX]; ll mx[MAX]; ll pcost[MAX]; void dfs(int x, int p = 0) { mx[x] = dep[x]; cnt++; range[x] = { cnt, cnt }; segv[range[x].first] = dep[x]; rev[cnt] = x; prt[x] = p; for (auto e : adj[x]) { int v = get_next(x, e); if (vis[v]) continue; if (v == p) continue; pcost[v] = get_cost(x, e); dep[v] = dep[x] + pcost[v]; sump[v] = get_cost(v, e); dfs(v, x); range[x].second = max(range[x].second, range[v].second); mx[x] = max(mx[x], mx[v]); sump[x] += sump[v]; } } void clearv(int v, int n) { while (v) { if (!pcost[v]) return; segtree::upd(1, n, range[v].first, range[v].second, -pcost[v]); pcost[v] = 0; v = prt[v]; if (!v) return; } } void make_tree(int x, ll add = 0) { get_num(x); int c = x; int n = num[c]; while (1) { bool changed = false; for (auto e : adj[c]) { int v = get_next(c, e); if (vis[v]) continue; if (num[v] > num[c]) continue; if (num[v] > n / 2) { c = v; changed = true; break; } } if (!changed) break; } dep[c] = 0; cnt = 0; sump[c] = 0; dfs(c); ans[1] = max(ans[1], sump[c] + add); int mx1, mx2; mx1 = mx2 = 0; for (auto e : adj[c]) { int v = get_next(c, e); if (vis[v]) continue; if (mx[v] > mx[mx2]) mx2 = v; if (mx[mx2] > mx[mx1]) swap(mx1, mx2); } int i; segtree::init(1, n); ll nsum = sump[c]; for (i = 1; i <= n; i++) { pli res; if (i == 1) res = segtree::query(1, n, range[mx1].first, range[mx1].second); else if (i == 2) res = segtree::query(1, n, range[mx2].first, range[mx2].second); else res = segtree::query(1, n, 1, n); nsum += res.first; clearv(rev[res.second], n); if (i > 1) ans[i] = max(ans[i], nsum + add); } vis[c] = 1; for (auto e : adj[c]) { int v = get_next(c, e); if (!vis[v]) make_tree(v, add + sump[c] - sump[v] + get_cost(c, e)); } } signed main() { ios::sync_with_stdio(false), cin.tie(0); int N; cin >> N; int i; ll sum = 0; for (i = 1; i < N; i++) { cin >> edges[i].first >> edges[i].second >> costs[i].first >> costs[i].second; adj[edges[i].first].push_back(i); adj[edges[i].second].push_back(i); sum += costs[i].first; sum += costs[i].second; } if (N == 2) ans[1] = max(costs[1].first, costs[2].first), ans[2] = sum; else make_tree(1); int Q; cin >> Q; while (Q--) { int a; cin >> a; cout << sum - ans[a] << ln; } }

Compilation message (stderr)

designated_cities.cpp: In function 'void segtree::init(int, int, int)':
designated_cities.cpp:28:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   28 |   int m = s + e >> 1;
      |           ~~^~~
designated_cities.cpp: In function 'void segtree::upd(int, int, int, int, ll, int)':
designated_cities.cpp:49:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   49 |   int m = s + e >> 1;
      |           ~~^~~
designated_cities.cpp: In function 'pli segtree::query(int, int, int, int, int)':
designated_cities.cpp:58:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   58 |   int m = s + e >> 1;
      |           ~~^~~
designated_cities.cpp: In function 'int get_cost(int, int)':
designated_cities.cpp:71:1: warning: control reaches end of non-void function [-Wreturn-type]
   71 | }
      | ^
#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...