Submission #716470

#TimeUsernameProblemLanguageResultExecution timeMemory
716470pavementConstruction of Highway (JOI18_construction)C++17
100 / 100
839 ms37184 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; #define int long long #define mp make_pair #define mt make_tuple #define pb push_back #define ppb pop_back #define eb emplace_back #define g0(a) get<0>(a) #define g1(a) get<1>(a) #define g2(a) get<2>(a) #define g3(a) get<3>(a) #define g4(a) get<4>(a) mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); using db = double; using ll = long long; using ld = long double; using ii = pair<int, int>; using iii = tuple<int, int, int>; using iiii = tuple<int, int, int, int>; using iiiii = tuple<int, int, int, int, int>; template<class key, class value = null_type, class cmp = less<key> > using ordered_set = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>; int N, idx, u[100005], v[100005], C[100005], par[100005], sz[100005], hv[100005], pos[100005], rev[100005], ft[100005]; vector<int> disc, adj[100005]; vector<iii> segs; stack<int> rb; int ls(int x) { return x & -x; } void reset() { while (!rb.empty()) { int x = rb.top(); ft[x] = 0; rb.pop(); } } void upd(int p, int v) { for (; p <= N; p += ls(p)) { rb.push(p); ft[p] += v; } } int qry(int p) { int r = 0; for (; p; p -= ls(p)) r += ft[p]; return r; } struct node { node *left, *right; int S, E, mxval, mival, pv; bool ip; node(int _s, int _e) : S(_s), E(_e), ip(0) { if (S == E) { mxval = mival = C[rev[S]]; return; } int M = (S + E) >> 1; left = new node(S, M); right = new node(M + 1, E); mxval = max(left->mxval, right->mxval); mival = min(left->mival, right->mival); } void prop() { if (S == E || !ip) return; left->mxval = left->mival = left->pv = right->mxval = right->mival = right->pv = pv; left->ip = right->ip = 1; ip = 0; } void get_seg(int l, int r) { if (l > E || r < S) return; if (l <= S && E <= r && mxval == mival) { segs.eb(S, E, mxval); return; } prop(); left->get_seg(l, r); right->get_seg(l, r); } void set(int l, int r, int v) { if (l > E || r < S) return; if (l <= S && E <= r) { mxval = mival = pv = v; ip = 1; return; } prop(); left->set(l, r, v); right->set(l, r, v); mxval = max(left->mxval, right->mxval); mival = min(left->mival, right->mival); } } *root; int get_sz(int n) { sz[n] = 1; for (auto u : adj[n]) { sz[n] += get_sz(u); } return sz[n]; } void dfs(int n) { pos[n] = ++idx; rev[pos[n]] = n; int cur_mx = -1; for (int i = 0; i < (int)adj[n].size(); i++) { if (sz[adj[n][i]] > cur_mx) { cur_mx = sz[adj[n][i]]; swap(adj[n][0], adj[n][i]); } } for (int i = 0; i < (int)adj[n].size(); i++) { if (i == 0) { hv[adj[n][i]] = hv[n]; } else { hv[adj[n][i]] = adj[n][i]; } dfs(adj[n][i]); } } main() { ios::sync_with_stdio(0); cin.tie(0); cin >> N; for (int i = 1; i <= N; i++) { cin >> C[i]; disc.pb(C[i]); } sort(disc.begin(), disc.end()); for (int i = 1; i <= N; i++) { C[i] = lower_bound(disc.begin(), disc.end(), C[i]) - disc.begin() + 1; } for (int i = 1; i < N; i++) { cin >> u[i] >> v[i]; par[v[i]] = u[i]; adj[u[i]].pb(v[i]); } get_sz(1); hv[1] = 1; dfs(1); root = new node(1, N); for (int i = 1; i < N; i++) { segs.clear(); for (int x = u[i]; x; x = par[hv[x]]) { root->get_seg(pos[hv[x]], pos[x]); root->set(pos[hv[x]], pos[x], C[v[i]]); } int cur = 0; sort(segs.begin(), segs.end()); reset(); for (auto [l, r, val] : segs) { cur += qry(N - val) * (r - l + 1); upd(N - val + 1, r - l + 1); } cout << cur << '\n'; } }

Compilation message (stderr)

construction.cpp:132:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  132 | main() {
      | ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...