Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <algorithm>
- #include <utility>
- #include <vector>
- #include <stack>
- #include <map>
- #include <queue>
- #include <set>
- #include <unordered_set>
- #include <unordered_map>
- #include <cstring>
- #include <cmath>
- #include <functional>
- #include <cassert>
- #include <iomanip>
- #include <numeric>
- #include <bitset>
- #include <sstream>
- #include <chrono>
- #include <random>
- #define ff first
- #define ss second
- #define ll long long
- #define ld long double
- #define PB push_back
- #define MP make_pair
- #define MT make_tuple
- #define EB emplace_back
- #define PoB pop_back
- #define LOG log2
- #define FOR(i,a,b) for (int i = (a); i < (b); ++i)
- #define F0R(i,a) FOR(i,0,a)
- #define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
- #define R0F(i,a) ROF(i,0,a)
- #define fch(t, v) for (auto t : v)
- #define sz(x) int(x.size())
- #define rsz resize
- #define gp(x) vector<vector<x>>
- #define btree vector<pii>
- #define vll vector<ll>
- #define Max(a, b, c) max(max(a,b),c)
- #define fMax(a, b, c, d) max(Max(a, b, c), dp)
- #define Min(a, b, c) min(min(a,b),c)
- #define Mid(a, b, c) max(min(a, b), min(max(a, b), c))
- #define st(a) set<a>
- #define gr(x) greater<x>
- #define gi greater<int>
- #define all(x) (x).begin(),(x).end()
- #define tri(x) tuple<x,x,x>
- #define pil pair<int, long>
- #define ull unsigned long long
- #define eps 1e-9
- //#define debug(x) cout << '>' << #x << ':' << x << endl;
- using namespace std;
- void __print(int x) {cerr << x;}
- void __print(long x) {cerr << x;}
- void __print(long long x) {cerr << x;}
- void __print(unsigned x) {cerr << x;}
- void __print(unsigned long x) {cerr << x;}
- void __print(unsigned long long x) {cerr << x;}
- void __print(float x) {cerr << x;}
- void __print(double x) {cerr << x;}
- void __print(long double x) {cerr << x;}
- void __print(char x) {cerr << '\'' << x << '\'';}
- void __print(const char *x) {cerr << '\"' << x << '\"';}
- void __print(const string &x) {cerr << '\"' << x << '\"';}
- void __print(bool x) {cerr << (x ? "true" : "false");}
- template<typename T, typename V>
- void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ", "; __print(x.second); cerr << '}';}
- template<typename T>
- void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? ", " : ""), __print(i); cerr << "}";}
- void _print() {cerr << "]\n";}
- template <typename T, typename... V>
- void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
- void println() {cerr << ">--------------------<" << endl;}
- void printm(vector<vector<int>>& mat) {
- cerr << "matrix: " << endl;
- for (int i = 0; i<(int)mat.size(); i++) {for (int j = 0; j<(int)mat[0].size(); j++) {cerr << mat[i][j] << " ";} cerr << endl;}
- }
- #ifndef ONLINE_JUDGE
- #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
- #else
- #define debug(x...)
- #endif
- typedef pair<int, int> pii;
- typedef pair<ll, ll> pll;
- typedef vector<int> vi;
- // templates
- template <class T> bool ckmin(T &a, const T &b) {return b<a ? a = b, 1 : 0;}
- template <class T> bool ckmax(T &a, const T &b) {return b>a ? a = b, 1 : 0;}
- mt19937_64 rng_ll(chrono::steady_clock::now().time_since_epoch().count());
- template <class T> using vc = vector<T>;
- template <class T> using p_q = priority_queue<T>;
- template <class T> using pqg = priority_queue<T, vc<T>, greater<T>>;
- int rng(int M) {return (int)(rng_ll()%M);}
- constexpr int INF = (int)2e9;
- int MOD = 998244353;
- constexpr ll LL_INF = (ll)3e18;
- constexpr int mod = (int)1e9 + 7;
- constexpr ll inverse = 500000004LL; // inverse of 2 modulo 1e9 + 7
- void setIO(const string& str) {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- if (str.empty()) return;
- freopen((str + ".in").c_str(), "r", stdin);
- freopen((str + ".out").c_str(), "w", stdout);
- }
- int N, T;
- vc<vi> adj;
- vll a, dp, s, t, leaf, pd;
- vi contains;
- struct LCA {
- int N; // assuming ONE INDEXED
- vector<vector<int>> adj, up;
- int L = 20;
- int timer = 0;
- vector<int> tin, tout;
- void dfs(int v, int par) { // par MUST BE EQUAL TO V at the start
- tin[v] = timer++;
- up[v][0] = par;
- for (int i = 1; i <= L; ++i) up[v][i] = up[up[v][i-1]][i-1];
- fch(u, adj[v]) if (u != par) dfs(u, v);
- tout[v] = timer++;
- }
- LCA(int n, int root, const vc<vi>& trump) {
- N = n;
- adj = trump;
- up.clear(), up.rsz(N+1, vi(L+1));
- tin.clear(), tin.rsz(N+1), tout.clear(), tout.rsz(N+1);
- timer = 0;
- dfs(root, root);
- }
- bool bruh(int u, int v) { // this function checks if u is ancestor of v
- return tin[u] <= tin[v] && tout[u] >= tout[v];
- }
- int lca(int u, int v) {
- if (bruh(u, v)) return u;
- if (bruh(v, u)) return v;
- for (int i = L; i >= 0; --i) if (!bruh(up[u][i], v)) u = up[u][i];
- return up[u][0];
- }
- };
- void dfs(int v) {
- s[v] = a[v];
- t[v] = 0;
- fch(u, adj[v]) {
- dfs(u);
- t[v] += 2 + t[u];
- s[v] += s[u];
- }
- sort(all(adj[v]), [&](const int& a, const int& b) {
- return s[b] * (t[a] + 2) < (t[b] + 2) * s[a];
- });
- ll time = 0;
- fch(u, adj[v]) {
- time++;
- dp[v] += dp[u] + s[u] * time;
- time += 1 + t[u];
- }
- }
- void dfs2(int v) {
- s[v] = a[v];
- t[v] = 0;
- fch(u, adj[v]) {
- dfs2(u);
- s[v] += s[u];
- t[v] += 2 + t[u];
- ckmax(leaf[v], leaf[u] + 1);
- }
- ll L = leaf[v] - 1;
- if (sz(adj[v]) == 0) {
- pd[v] = dp[v];
- return;
- }
- sort(all(adj[v]), [&](const int& a, const int& b) {
- return s[b] * (t[a] + 2) < (t[b] + 2) * s[a];
- });
- ll time = 0;
- int M = sz(adj[v]);
- vll psum;
- fch(u, adj[v]) {
- time++;
- dp[v] += dp[u] + s[u] * time;
- time += 1 + t[u];
- ll prev = (!psum.empty() ? psum.back() : 0);
- psum.PB(prev + 2 + t[u]);
- }
- ll ssum = 0;
- for (int i = M-1; i >= 0; --i) {
- int u = adj[v][i];
- if (leaf[u] == L) {
- ll end_minus = (2 + t[u]) * (ssum);
- ll u_time = (i > 0 ? psum[i-1] : 0) * s[u];
- ll new_u_time = (psum[M-1] - (2 + t[u])) * s[u];
- ckmin(pd[v], dp[v] - end_minus - u_time + new_u_time - dp[u] + pd[u]);
- }
- ssum += s[u];
- }
- }
- void solve0() {
- dfs(1);
- cout << t[1] << ' ' << dp[1] << '\n';
- }
- void solve1() {
- leaf.rsz(N+1, 0), pd.rsz(N+1, LL_INF);
- dfs2(1);
- cout << t[1] - leaf[1] << ' ' << pd[1] << '\n';
- }
- int main() { // TIME YOURSELF !!!
- setIO("");
- cin >> N >> T;
- adj.rsz(N+1), a.rsz(N+1), dp.rsz(N+1, 0), s.rsz(N+1), t.rsz(N+1), contains.rsz(N+1, 0);
- for (int i = 2; i <= N; i++) {
- int pi, ai;
- cin >> pi >> ai;
- adj[pi].PB(i);
- a[i] = ai;
- }
- if (T == 0) solve0();
- else solve1();
- return 0;
- }
- // CHECK LONG LONGS, binary search on ans?
- // Do something, start simpler
- // IBM motto: THINK
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement