Submission #546780

#TimeUsernameProblemLanguageResultExecution timeMemory
546780gimabd30Fireworks (APIO16_fireworks)C++17
100 / 100
180 ms39580 KiB
//#define _GLIBCXX_DEBUG //#pragma GCC optimize("Ofast") //#pragma GCC optimize("unroll-loops") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #include <bits/stdc++.h> using namespace std; #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; template<typename T> using ordered_set = tree<T, null_type, less < T>, rb_tree_tag, tree_order_statistics_node_update>; template<typename T> using normal_queue = priority_queue <T, vector<T>, greater<>>; mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); #define ll long long #define trace(x) cout << #x << ": " << (x) << endl; #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) #define uniq(x) x.resize(unique(all(x)) - begin(x)) #define ld long double #define sz(s) ((int) size(s)) #define pii pair<int, int> #define mp(x, y) make_pair(x, y) #define int128 __int128 #define pb push_back #define eb emplace_back template<typename T> bool ckmin(T &x, T y) { if (x > y) { x = y; return true; } return false; } template<typename T> bool ckmax(T &x, T y) { if (x < y) { x = y; return true; } return false; } int bit(int x, int b) { return (x >> b) & 1; } int rand(int l, int r) { return (int) ((ll) rnd() % (r - l + 1)) + l; } //soryan za musor sverhu const ll infL = 3e18; const int infI = 1e9 + 7; const int N = 300001; const ll mod = 1e9 + 7; const ld eps = 1e-9; priority_queue<ll> pq[N]; int p[N], c[N]; ll k[N], b[N]; //это уравнение прямой при больших X int main() { ios::sync_with_stdio(false); cin.tie(nullptr); //https://codeforces.com/blog/entry/47821 int n, m; cin >> n >> m; auto mrg = [](int i) { if (sz(pq[i]) > sz(pq[p[i]])) swap(pq[i], pq[p[i]]); k[p[i]] += k[i]; b[p[i]] += b[i]; while (!pq[i].empty()) { auto v = pq[i].top(); pq[i].pop(); pq[p[i]].push(v); } }; for (int i = 1; i < n + m; ++i) { cin >> p[i] >> c[i]; --p[i]; } for (int i = n; i < n + m; ++i) { k[i] = 1; b[i] = -c[i]; pq[i].push(c[i]); pq[i].push(c[i]); mrg(i); } for (int i = n - 1; i > 0; --i) { //we don't need slopes with k > 1 because we just can increase c[i[ by one all the time while (k[i] > 1) { --k[i]; b[i] += pq[i].top(); // y = kx+b = (a-1)x + (b + x) at slope changing point pq[i].pop(); } auto R = pq[i].top(); pq[i].pop(); auto L = pq[i].top(); pq[i].pop(); L += c[i]; R += c[i]; //moving slopes with K = 0, 1 b[i] -= c[i]; //we shifted to the right by c[i] and k = 1 so b[i] decreases by c[i] pq[i].push(L); pq[i].push(R); mrg(i); } while (k[0] > 0) { --k[0]; b[0] += pq[0].top();// y = kx+b = (a-1)x + (b + x) at slope changing point pq[0].pop(); } cout << b[0]; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...