Cod sursa(job #3156354)

Utilizator alexdumitruAlexandru Dumitru alexdumitru Data 11 octombrie 2023 11:57:53
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.42 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int NMAX = 100005;

struct SegTree {
    vector<int> aint;
    vector<int> vals;
    int n;
    void build(int nod, int st, int dr)
    {
        if(st == dr)
        {
            aint[nod] = vals[st];
            return;
        }
        int mij = (st + dr) / 2;
        build(nod * 2, st, mij);
        build(nod * 2 + 1, mij + 1, dr);
        aint[nod] = max(aint[nod * 2], aint[nod * 2 + 1]);
    }
    SegTree()
    {

    }
    SegTree(vector<int> nodes)
    {
        n = nodes.size();
        vals.resize(n + 1);
        for(int i = 1; i <= n; i++)
            vals[i] = nodes[i - 1];
        aint.resize(4 * n + 1);
        build(1, 1, n);
    }
    int query(int nod, int st, int dr, int l, int r)
    {
        if(l <= st && dr <= r)
            return aint[nod];
        int mij = (st + dr) / 2;
        int v1 = 0, v2 = 0;
        if(l <= mij)
            v1 = query(nod * 2, st, mij, l, r);
        if(mij < r)
            v2 = query(nod * 2 + 1, mij + 1, dr, l, r);
        return max(v1, v2);
    }
    void update(int nod, int st, int dr, int poz, int val)
    {
        if(st == dr)
        {
            aint[nod] = val;
            return;
        }
        int mij = (st + dr) / 2;
        if(poz <= mij)
            update(nod * 2, st, mij, poz, val);
        else update(nod * 2 + 1, mij + 1, dr, poz, val);
        aint[nod] = max(aint[nod * 2], aint[nod * 2 + 1]);
    }
};



int n, q;
vector<int> g[NMAX];
int v[NMAX];

int lvl[NMAX];
int sz[NMAX];
int maxSon[NMAX];
int dad[NMAX];
int id[NMAX];
int pos[NMAX];
int csz[NMAX];
int chainBoss[NMAX];
int cnt;

vector<int> nodes[NMAX];
SegTree chain[NMAX];

void getW(int nod, int tata)
{
    dad[nod] = tata;
    lvl[nod] = lvl[tata] + 1;
    sz[nod] = 1;
    for(auto it : g[nod])
        if(it != tata)
        {
            getW(it, nod);
            sz[nod] += sz[it];
            if(sz[it] > sz[maxSon[nod]])
                maxSon[nod] = it;
        }
}

void dfs(int nod)
{
    id[nod] = cnt;
    nodes[cnt].push_back(v[nod]);
    pos[nod] = ++csz[cnt];
    if(!maxSon[nod])
    {
        chain[cnt] = SegTree(nodes[cnt]);
        return;
    }
    dfs(maxSon[nod]);
    for(auto it : g[nod])
        if(it != dad[nod] && it != maxSon[nod])
        {
            chainBoss[++cnt] = it;
            dfs(it);
        }
}

int query(int x, int y)
{
    if(id[x] == id[y])
        return chain[id[x]].query(1, 1, csz[id[x]], min(pos[x], pos[y]), max(pos[x], pos[y]));
    if(lvl[chainBoss[id[x]]] < lvl[chainBoss[id[y]]])
        swap(x, y);
    return max(chain[id[x]].query(1, 1, csz[id[x]], 1, pos[x]), query(dad[chainBoss[id[x]]], y));
}

void update(int x, int y)
{
    chain[id[x]].update(1, 1, csz[id[x]], pos[x], y);
}

void solve()
{
    fin >> n >> q;
    for(int i = 1; i <= n; i++)
        fin >> v[i];
    for(int i = 1; i < n; i++)
    {
        int u, v;
        fin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    getW(1, 0);
    cnt = 1;
    chainBoss[1] = 1;
    dfs(1);
    return;
    while(q--)
    {
        int tip, x, y;
        fin >> tip >> x >> y;
        if(tip == 0)
            update(x, y);
        else fout << query(x, y) << '\n';
    }
}

int main()
{
    solve();
    return 0;
}