Submission #1305365

#TimeUsernameProblemLanguageResultExecution timeMemory
1305365TymondConstruction of Highway (JOI18_construction)C++20
100 / 100
396 ms28212 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define fi first
#define se second
#define vi vector<int>
#define vll vector<long long>
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
mt19937_64 rng64(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int rand(int l,int r){return uniform_int_distribution<int>(l, r)(rng);}
inline ll rand(ll l,ll r){return uniform_int_distribution<ll>(l, r)(rng64);}
#ifdef DEBUG
auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";}
auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";}
#define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X)
#else
#define debug(...){}
#endif

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

const int INF = 1e9;
const int MAXN = 1e5 + 7;
const int BASE = (1 << 18);
int A[MAXN];
vi g[MAXN];
int parent[MAXN];
int sz[MAXN];
vector<pii> edges;
int rep[MAXN];
set<pii> segments[MAXN];
int dep[MAXN];
ll tree[2 * BASE + 7];
int n;

void dfsInit(int v, int d){
    sz[v] = 1;
    dep[v] = d;
    for(auto ele : g[v]){
        dfsInit(ele,d + 1);
        sz[v] += sz[ele];
    }

    for(int i = 1; i < sz(g[v]); i++){
        if(sz[g[v][i]] > sz[g[v][0]]){
            swap(g[v][i], g[v][0]);
        }
    }
}

void dfsHld(int v, int r){
    rep[v] = r;

    if(sz(g[v]) == 0){
        return;
    }
    dfsHld(g[v][0], r);
    for(int i = 1; i < sz(g[v]); i++){
        dfsHld(g[v][i], g[v][i]);
    }
}

void upd(int ind, ll ch){
    ind += BASE;
    while(ind > 0){
        tree[ind] += ch;
        ind /= 2;
    }
}

ll query(int v, int l, int p, int a, int b){
    if(p < a || b < l || b < a){
        return 0LL;
    }

    if(a <= l && p <= b){
        return tree[v];
    }
    int mid = (l + p) / 2;
    return (ll)query(2 * v, l, mid, a, b) + query(2 * v + 1, mid + 1, p, a, b);
}

ll countInv(vector<pii>& vec){
    ll res = 0LL;
    for(auto ele : vec){
        res = (ll)res + (ll)ele.fi * query(1, 0, BASE - 1, ele.se + 1, BASE - 1);
        upd(ele.se, ele.fi);
    }

    for(auto ele : vec){
        upd(ele.se, -ele.fi);
    }
    return res;
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    
    cin >> n;
    map<int, int> xd;
    for(int i = 1; i <= n; i++){
        cin >> A[i];
        xd[A[i]] = 1;
    }

    int lol = 0;
    for(auto& ele : xd){
        ele.se = lol++;
    }

    for(int i = 1; i <= n; i++){
        A[i] = xd[A[i]];
    }

    parent[1] = 0;
    for(int i = 1; i < n; i++){
        int x, y;
        cin >> x >> y;
        parent[y] = x;
        g[x].pb(y);
        edges.pb(mp(x, y));
    }
    segments[1].insert(mp(0, A[1]));

    dfsInit(1, 0);
    dfsHld(1, 1);
    // for(int i = 1; i <= n; i++){
    //     cerr << dep[i] << ' ' << rep[i] << '\n';
    // }

    // cerr << "========\n";
    // for(int i = 1; i <= n; i++){
    //     cerr << "=== " << i << '\n';
    //     for(auto ele : segments[i]){
    //         cerr << ele << '\n';
    //     }
    // }

    for(auto [a, b] : edges){
        //policz wynik
        vector<pii> vec = {};
        while(a != 0){
            vector<pii> nvec = {};
            int lst = dep[rep[a]];
            auto it = segments[rep[a]].begin();
            while(lst <= dep[a]){
                nvec.pb(mp(min(dep[a], (*it).fi) - lst + 1, (*it).se));
                lst = min(dep[a], (*it).fi) + 1;
                it++;
            }
            a = parent[rep[a]];
            reverse(all(nvec));
            for(auto ele : nvec){
                vec.pb(ele);
            }
            vector<pii>().swap(nvec);
        }

        reverse(all(vec));
        cout << countInv(vec) << '\n';
        vector<pii>().swap(vec);
        //upd info
        int val = A[b];
        while(b != 0){
            while(sz(segments[rep[b]]) && (*segments[rep[b]].begin()).fi <= dep[b]){
                segments[rep[b]].erase(segments[rep[b]].begin());
            }
            segments[rep[b]].insert(mp(dep[b], val));
            b = parent[rep[b]];
        }

        // cerr << "========\n";
        // for(int i = 1; i <= n; i++){
        //     cerr << "=== " << i << '\n';
        //     for(auto ele : segments[i]){
        //         cerr << ele << '\n';
        //     }
        // }
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...