Submission #62573

#TimeUsernameProblemLanguageResultExecution timeMemory
62573qkxwsmConstruction of Highway (JOI18_construction)C++11
100 / 100
923 ms63676 KiB
//whatever #include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef complex<ld> cd; typedef pair<int, int> pi; typedef pair<ll,ll> pl; typedef pair<ld,ld> pd; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; typedef vector<cd> vcd; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; #define FOR(i, a, b) for (int i=a; i<(b); i++) #define F0R(i, a) for (int i=0; i<(a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() const int MOD = 1000000007; const ll INF = 1e18; const int MX = 100001; template<class T, int SZ> struct BIT { T bit[SZ+1]; vpi v; BIT() { memset(bit,0,sizeof bit); } void upd(int k, T val) { // add val to index k v.pb({k,val}); for( ;k <= SZ; k += (k&-k)) bit[k] += val; } void clr() { for (auto a: v) upd(a.f,-a.s); v.clear(); } T query(int k) { T temp = 0; for (;k > 0;k -= (k&-k)) temp += bit[k]; return temp; } T query(int l, int r) { return query(r)-query(l-1); } // range query [l,r] }; BIT<int,MX> B; vector<vi> graph; template <int V> struct HeavyLight { // sum queries, sum updates int parent[V], heavy[V], depth[V]; int root[V], treePos[V]; vpi dat[V]; void init() { int n = sz(graph)-1; FOR(i,1,n+1) heavy[i] = -1; parent[1] = -1, depth[1] = 0; dfs(1); for (int i = 1; i <= n; ++i) if (parent[i] == -1 || heavy[parent[i]] != i) for (int j = i; j != -1; j = heavy[j]) { root[j] = i; dat[i].pb({0,1}); } } int dfs(int v) { int size = 1, maxSubtree = 0; for (auto u : graph[v]) if (u != parent[v]) { parent[u] = v; depth[u] = depth[v] + 1; int subtree = dfs(u); if (subtree > maxSubtree) heavy[v] = u, maxSubtree = subtree; size += subtree; } return size; } ll query(int v) { int r = root[v], tot = depth[v]-depth[r]+1; vpi tmp; int TOT = tot; F0Rd(i,sz(dat[r])) { auto a = dat[r][i]; if (a.s >= TOT) { tmp.pb({a.f,TOT}); break; } else { TOT -= a.s; tmp.pb(a); } } /*cout << v << " " << r << " " << dat[r].back().f << "\n"; for (auto a: tmp) cout << a.f << " " << a.s << "\n"; exit(0);*/ reverse(all(tmp)); ll ret = 0; for (auto x: tmp) { ret += (ll)x.s*B.query(x.f-1); B.upd(x.f,x.s); } return ret; } void upd(int v, int val) { int r = root[v], tot = depth[v]-depth[r]+1; // cout << v << " " << tot << "\n"; int TOT = tot; while (dat[r].back().s < TOT) { TOT -= dat[r].back().s; dat[r].pop_back(); } dat[r].back().s -= TOT; if (dat[r].back().s == 0) dat[r].pop_back(); dat[r].pb({val,tot}); // cout << "AH " << val << " " << tot << "\n"; // exit(0); } ll queryPath(int v) { //cout << v << " " << root[v] << " " << sz(dat[v]) << "\n"; // exit(0); ll ans = 0; B.clr(); for (; v != -1; v = parent[root[v]]) ans += query(v); return ans; } void updPath(int v, int val) { for (; v != -1; v = parent[root[v]]) upd(v,val); } }; HeavyLight<1<<17> H; int N,M,A[MX]; pi p[MX]; void compress() { map<int,int> m; FOR(i,1,N+1) m[A[i]] = 0; int co = 0; for (auto& a: m) a.s = ++co; FOR(i,1,N+1) { A[i] = m[A[i]]; // cout << A[i] << "\n"; } // exit(0); } int main() { cin >> N; graph.resize(N+1); FOR(i,1,N+1) cin >> A[i]; compress(); F0R(i,N-1) { cin >> p[i].f >> p[i].s; graph[p[i].f].pb(p[i].s); graph[p[i].s].pb(p[i].f); } H.init(); H.updPath(1,A[1]); // exit(0); F0R(i,N-1) { cout << H.queryPath(p[i].f) << "\n"; // exit(0); H.updPath(p[i].s,A[p[i].s]); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...