Submission #61485

#TimeUsernameProblemLanguageResultExecution timeMemory
61485BenqMin-max tree (BOI18_minmaxtree)C++11
100 / 100
637 ms39652 KiB
#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 = 70010; vi adj[MX]; set<array<int,3>> ADJ[MX]; priority_queue<int> mx[MX], mn[MX]; int N; bool done[MX]; map<int,int> m; vi rm; void merge(priority_queue<int>& a, priority_queue<int>& b) { if (sz(a) < sz(b)) swap(a,b); while (sz(b)) a.push(b.top()), b.pop(); } void del(priority_queue<int>& a) { while (sz(a) > 1) { int x = a.top(); a.pop(); if (a.top() == x) a.pop(); else { a.push(x); break; } } } void merge(int a, int b) { // cout << "TT " << sz(mn[a]) << " " << sz(mn[b]) << "\n"; merge(mn[a],mn[b]); //cout << "TT " << sz(mn[a]) << " " << sz(mn[b]) << "\n"; del(mn[a]); merge(mx[a],mx[b]); del(mx[a]); } void dfs(int x, int p) { for (int i: adj[x]) if (i != p) { dfs(i,x); // cout << "OH " << i << " " << x << "\n"; merge(x,i); } int lo = (sz(mn[x]) ? mn[x].top() : -MOD); int hi = (sz(mx[x]) ? -mx[x].top() : MOD); if (p) { // cout << "ZZ " << x << " " << p << "\n"; ADJ[m[lo]].insert({m[hi],x,p}); ADJ[m[hi]].insert({m[lo],x,p}); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N; F0R(i,N-1) { // int A = rand() % (i+1)+1, B = i+2; int A,B; cin >> A >> B; adj[A].pb(B), adj[B].pb(A); } int K; cin >> K; m[MOD] = 0, m[-MOD] = 1; rm.pb(MOD), rm.pb(-MOD); F0R(i,K) { char c; cin >> c; int x,y,z; cin >> x >> y >> z; if (c == 'M') mx[x].push(-z), mx[y].push(-z); else mn[x].push(z), mn[y].push(z); m[z] = i+2, rm.pb(z); } dfs(1,0); set<pi> S; FOR(i,2,K+2) S.insert({sz(ADJ[i]),i}); done[0] = done[1] = 1; while (sz(S)) { auto a = *S.begin(); S.erase(a); done[a.s] = 1; // cout << "OOOPS " << sz(ADJ[a.s]) << "\n"; auto it = *ADJ[a.s].begin(); ADJ[a.s].erase(it); if (!done[it[0]]) S.erase({sz(ADJ[it[0]]),it[0]}); ADJ[it[0]].erase({a.s,it[1],it[2]}); if (!done[it[0]]) { S.insert({sz(ADJ[it[0]]),it[0]}); assert(sz(ADJ[it[0]])); } cout << it[1] << " " << it[2] << " " << rm[a.s] << "\n"; } F0R(i,K+2) for (auto a: ADJ[i]) if (a[0] >= i) cout << a[1] << " " << a[2] << " " << rm[i] << "\n"; } /* Look for: * the exact constraints (multiple sets are too slow for n=10^6 :( ) * special cases (n=1?) * overflow (ll vs int?) * array bounds */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...