답안 #1020431

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1020431 2024-07-12T04:27:23 Z nathan4690 Tree Rotations (POI11_rot) C++17
100 / 100
317 ms 44368 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define pll ll
#define ld long double
#define el cout << '\n'
#define f1(i,n) for(ll i=1;i<=n;i++)
#define __file_name ""
using namespace std;
using namespace __gnu_pbds;
#define ordered_set tree<pll, null_type, less<pll>, rb_tree_tag, tree_order_statistics_node_update>
using namespace std;
const ll maxn = 4e5+5, inf=1e18;

/*
// Be yeu tle roi cay qua
ll dfs(ll u, ll p){
    if(a[u]){
        // cout << u << ' ' << a[u];el;
        values[u].insert(a[u]);
        return 0;
    }
    ll resp = 0;
    ll le = 0, ri = 0;
    for(ll c: G[u]){
        if(c != p){
            resp += dfs(c, u);
            if(le == 0) le = c;
            else ri = c;
        }
    }
    if(values[ri].size() < values[le].size()) swap(values[ri], values[le]);
    // le < ri
    ll res1 = 0, res2 = 0;
    // res1: count inversion if le comes before ri
    // res2: count inversions if le comes after ri
    for(auto item: values[le]){
        res1 += values[ri].order_of_key(item);
        res2 += values[ri].size() - values[ri].order_of_key(item+1);
    }
    // cout << u << ' ' << res1 << ' ' << res2;el;
    for(ll c: G[u]){
        if(c != p){
            if(values[c].size() > values[u].size()) values[u].swap(values[c]);
            for(auto item: values[c]){
                values[u].insert(item);
            }
            values[c].clear();
        }
    }
    return resp + min(res1, res2);
}
*/

ll n,a[maxn],sz[maxn];
pair<ll,ll> bit[maxn];
vector<ll> G[maxn];
vector<ll> sus;

void update(ll idx, pair<ll,ll> v){
    while(idx <= n){
        bit[idx].first += v.first;
        bit[idx].second += v.second;
        idx += idx & (-idx);
    }
}

pair<ll,ll> getSum(ll idx){
    // {sum, count}
    pair<ll,ll> res = {0ll, 0ll};
    while(idx > 0){
        res.first += bit[idx].first;
        res.second += bit[idx].second;
        idx -= idx & (-idx);
    }
    return res;
}

void dfs_size(ll u, ll p){
    sz[u] = 1;
    for(ll c: G[u]){
        if(c != p){
            dfs_size(c, u);
            sz[u] += sz[c];
        }
    }
}

void delete_(ll u, ll p){
    if(a[u]){
        update(a[u], {-1ll, -1ll});
        return;
    }
    for(ll c: G[u]){
        if(c != p){
            delete_(c, u);
        }
    }
}

void add_(ll u, ll p){
    if(a[u]){
        update(a[u], {1ll , 1ll});
        return;
    }
    // update(order[u], {c[u], 1ll});
    for(ll c: G[u]){
        if(c != p){
            add_(c, u);
        }
    }
}

ll dfslow(ll u, ll p){
    if(a[u]){
        return getSum(a[u] - 1).first;
    }
    ll res = 0;
    for(ll c: G[u]){
        if(c != p){
            res += dfslow(c, u);
        }
    }
    return res;
}

ll dfshigh(ll u, ll p){
    if(a[u]){
        return getSum(n).first - getSum(a[u]).first;
    }
    ll res = 0;
    for(ll c: G[u]){
        if(c != p){
            res += dfshigh(c, u);
        }
    }
    return res;
}

ll dfs(ll u, ll p){
    ll msz = -1, v0 = 0;
    for(ll c: G[u]){
        if(c != p){
            if(sz[c] > msz){
                msz = sz[c];
                v0 = c;
            }
        }
    }
    if(msz == -1){
        update(a[u], {1ll , 1ll});
        return 0;
    }
    ll res = 0;
    for(ll c: G[u]){
        if(c != p && c != v0){
            res += dfs(c, u);
            delete_(c, u);
        }
    }
    res += dfs(v0, u);
    ll res1 = 0, res2 = 0;
    for(ll c: G[u]){
        if(c != p && c != v0){
            res1 += dfslow(c, u);
            res2 += dfshigh(c, u);
        }
    }
    for(ll c: G[u]){
        if(c != p && c != v0){
            add_(c, u);
        }
    }
    // cout << u << ' ' << res1 << ' ' << res2;el;
    return res + min(res1, res2);
}

ll timer = 0;

ll readInput(){
    ll v; cin >> v;
    ll myval = timer;
    timer++;
    if(v){
        a[myval] = v;
    }else{
        ll c1 = readInput(), c2 = readInput();
        G[c1].push_back(myval);
        G[myval].push_back(c1);
        G[c2].push_back(myval);
        G[myval].push_back(c2);
    }
    return myval;
}

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    if(fopen(__file_name ".inp", "r")){
        freopen(__file_name ".inp","r",stdin);
        freopen(__file_name ".out","w",stdout);
    }
    // code here
    cin >> n;
    timer = 1;
    ll root = readInput();
    n = timer - 1;
    dfs_size(root, 0);
    cout << dfs(root, 0);
    return 0;
}

/*
Code by: Nguyen Viet Trung Nhan
Cau Giay Secondary School
*/

Compilation message

rot.cpp: In function 'int main()':
rot.cpp:201:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  201 |         freopen(__file_name ".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rot.cpp:202:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  202 |         freopen(__file_name ".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 9816 KB Output is correct
2 Correct 4 ms 9816 KB Output is correct
3 Correct 5 ms 9820 KB Output is correct
4 Correct 4 ms 9820 KB Output is correct
5 Correct 4 ms 9628 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 9816 KB Output is correct
2 Correct 4 ms 9820 KB Output is correct
3 Correct 4 ms 9820 KB Output is correct
4 Correct 4 ms 9820 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 10072 KB Output is correct
2 Correct 5 ms 9820 KB Output is correct
3 Correct 4 ms 9820 KB Output is correct
4 Correct 4 ms 9960 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 10588 KB Output is correct
2 Correct 7 ms 10332 KB Output is correct
3 Correct 6 ms 10588 KB Output is correct
4 Correct 6 ms 10588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 12124 KB Output is correct
2 Correct 14 ms 11544 KB Output is correct
3 Correct 41 ms 13660 KB Output is correct
4 Correct 12 ms 12076 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 66 ms 16476 KB Output is correct
2 Correct 35 ms 17756 KB Output is correct
3 Correct 40 ms 19532 KB Output is correct
4 Correct 41 ms 19792 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 40 ms 26712 KB Output is correct
2 Correct 50 ms 24400 KB Output is correct
3 Correct 62 ms 22356 KB Output is correct
4 Correct 51 ms 21840 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 70 ms 26192 KB Output is correct
2 Correct 66 ms 26964 KB Output is correct
3 Correct 68 ms 30548 KB Output is correct
4 Correct 86 ms 30036 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 219 ms 35920 KB Output is correct
2 Correct 150 ms 34640 KB Output is correct
3 Correct 122 ms 34644 KB Output is correct
4 Correct 147 ms 34384 KB Output is correct
5 Correct 246 ms 32336 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 158 ms 36436 KB Output is correct
2 Correct 141 ms 42324 KB Output is correct
3 Correct 162 ms 39872 KB Output is correct
4 Correct 123 ms 43308 KB Output is correct
5 Correct 317 ms 35664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 151 ms 37420 KB Output is correct
2 Correct 129 ms 38368 KB Output is correct
3 Correct 245 ms 36608 KB Output is correct
4 Correct 173 ms 37532 KB Output is correct
5 Correct 121 ms 44368 KB Output is correct
6 Correct 316 ms 36436 KB Output is correct