제출 #1236385

#제출 시각아이디문제언어결과실행 시간메모리
1236385just트리 (IOI24_tree)C++20
0 / 100
47 ms24732 KiB
#include "tree.h"

#include "bits/stdc++.h"
using namespace std;

#define vec vector
#define int long long
#define all(x) (x).begin(), (x).end()

const int mod = 1e9 + 7;
const int inf = 1e18;

using pii = pair<int, int>;

template<typename T>
void print(const vec<T> &a) {
    for(auto x: a) cerr << x << " ";
    cerr << endl;
}

int n;
vec<int> p, w;
vec<vec<int>> adj;
int l, r;

pii  memo[100'100][2];
bool done[100'100][2] = { 0 };
pii calc(int u, bool mn) {
    if (done[u][mn]) return memo[u][mn];
    
    done[u][mn] = true;
    
    if (adj[u].empty()) {
        return memo[u][mn] = {l, l * w[u]};
    }
    
    int ans_sum = l;
    int ans_cost = inf;
    
    int cost = 0;
    int sum = l * adj[u].size();
    for (int v: adj[u]) cost += calc(v, true).second;
    
    if (mn == true) {
        ans_cost = min(ans_cost, cost + abs(sum - l) * w[u]);
    } else {
        int cur_cost, cur_sum;
        if (sum < l) {
            cur_cost = cost + abs(sum - l) * w[u];
            cur_sum = l;
        } else if (sum <= r) {
            cur_cost = cost;
            cur_sum = sum;
        } else {
            cur_cost = cost + abs(sum - r) * w[u];
            cur_sum = r;
        }
        
        
        if (cur_cost == ans_cost) ans_sum = min(ans_sum, cur_sum);
        else if (cur_cost < ans_cost) ans_cost = cur_cost, ans_sum = cur_sum;
    }
    
    for(int v: adj[u]) {
        cost -= calc(v, true).second;
        sum -= l;
        
        pii relax = calc(v, false);
        cost += relax.second;
        sum += relax.first;
        
        if (mn == true) {
            ans_cost = min(ans_cost, cost + abs(sum - l) * w[u]);
        } else {
            int cur_cost, cur_sum;
            if (sum < l) {
                cur_cost = cost + abs(sum - l) * w[u];
                cur_sum = l;
            } else if (sum <= r) {
                cur_cost = cost;
                cur_sum = sum;
            } else {
                cur_cost = cost + abs(sum - r) * w[u];
                cur_sum = r;
            }
            
            
            if (cur_cost == ans_cost) ans_sum = min(ans_sum, cur_sum);
            else if (cur_cost < ans_cost) ans_cost = cur_cost, ans_sum = cur_sum;
        }
    }
    
    return memo[u][mn] = {ans_sum, ans_cost};
}


void init(vec<signed> P, vec<signed> W) {
    n = P.size();
    p.resize(n);
    w.resize(n);
    
    for(int i = 0; i < n; i++) p[i] = P[i], w[i] = W[i];
    
    adj.resize(n);
    for (int i = 0; i < n; i++) if (p[i] != -1) adj[p[i]].push_back(i);
    for (int i = 0; i < n; i++) sort(all(adj[i]), [&](int a, int b) { return w[a] > w[b]; });
}

int query(signed L, signed R) {
    l = L, r = R;
    memset(done, false, sizeof(done));
    return calc(0, false).second;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...