Cod sursa(job #3317899)

Utilizator Andrei-Dani-10Pisla Andrei Daniel Andrei-Dani-10 Data 25 octombrie 2025 23:09:19
Problema Heavy Path Decomposition Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.06 kb
#include <fstream>

#include <vector>
#include <algorithm>

using namespace std;

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

const int nmax = 1e5;
const int maxint = (1 << 30);
int n, nrq, type, x, y, costt[nmax + 2];

vector <int> muchii[nmax + 2];
vector <int> nodepaths[nmax + 2];

int heavypath[nmax + 2], subtreesize[nmax + 2];
int wherenodeidx[nmax + 2], withtag[nmax + 2];
int depth[nmax + 2], father[nmax + 2];

int headpath[nmax + 2];

void dfsbuildhld(int node, int parent){

    subtreesize[node] = 1;

    depth[node] = 1 + depth[parent];
    father[node] = parent;

    int heavyson = 0;
    for(auto nxt : muchii[node]){
        if(nxt != parent){
            dfsbuildhld(nxt, node);
            subtreesize[node] += subtreesize[nxt];

            if(subtreesize[heavyson] < subtreesize[nxt])
                heavyson = nxt;
        }
    }

    if(!heavyson){ heavypath[heavyson]++; }

    heavypath[node] = heavypath[heavyson];
    nodepaths[heavypath[node]].push_back(node);

    return;
}

struct segmenttree{
    int tree[4 * nmax + 2], mxx;

    void build(int node, int st, int dr){
        if(st == dr){
            tree[node] = costt[withtag[st]];
        }else{
            int mij = (st + dr) >> 1;
            build((node << 1), st, mij);
            build((node << 1), mij + 1, dr);

            tree[node] = max(tree[(node << 1)], tree[(node << 1) | 1]);
        }
    }

    void update(int node, int st, int dr, int idx){
        if(st == dr){
            tree[node] = costt[withtag[st]];
        }else{
            int mij = (st + dr) >> 1;
            if(idx <= mij) update((node << 1), st, mij, idx);
            if(mij < idx) update((node << 1) | 1, mij + 1, dr, idx);

            tree[node] = max(tree[(node << 1)], tree[(node << 1) | 1]);
        }
    }

    int query(int node, int st, int dr, int lf, int rg){
        if(lf <= st && dr <= rg){
            return tree[node];
        }else{
            int mij = (st + dr) >> 1, maxival = 0;

            if(lf <= mij) maxival = max(maxival, query((node << 1), st, mij, lf, rg));
            if(mij < rg) maxival = max(maxival, query((node << 1) | 1, mij + 1, dr, lf, rg));

            return maxival;
        }
    }
} myaint;

int hldquery(int a, int b){

    int maxpath = 0;

    for(; a != b; ){
        if(depth[a] < depth[b])
            swap(a, b);

        maxpath = max(maxpath, costt[a]);
        a = father[a];
    }

    maxpath = max(maxpath, costt[a]);

    return maxpath;

    /**int maxpath = 0;

    for(; headpath[a] != headpath[b]; ){
        if(depth[headpath[a]] < depth[headpath[b]]){
            swap(a, b);
        }

        maxpath = max(maxpath, myaint.query(1, 1, n, wherenodeidx[headpath[a]], wherenodeidx[a]));

        a = father[headpath[a]];
    }

    if(wherenodeidx[a] > wherenodeidx[b]){ swap(a, b); }
    maxpath = max(maxpath, myaint.query(1, 1, n, wherenodeidx[a], wherenodeidx[b]));

    return maxpath;**/
}

int main(){

    in.tie(NULL) -> sync_with_stdio(false); out.tie(NULL);

    in>>n>>nrq;
    for(int i = 1; i <= n; i++){
        in>>costt[i];
    }

    for(int i = 1; i <= n - 1; i++){
        in>>x>>y;
        muchii[x].push_back(y);
        muchii[y].push_back(x);
    }

    dfsbuildhld(1, 0);

    for(int it = 1; it <= heavypath[0]; it++){
        reverse(nodepaths[it].begin(), nodepaths[it].end());

        for(auto f : nodepaths[it]){
            wherenodeidx[f] = (++wherenodeidx[0]);
            withtag[wherenodeidx[0]] = f;

            headpath[f] = nodepaths[it][0];
        }

        ///out<<"Path: "<<it<<" -> ";
        ///for(auto f : nodepaths[it])
        ///    out<<f<<" "; out<<"\n";
    }

    myaint.build(1, 1, n); ///build base costs

    for(int itq = 1; itq <= nrq; itq++){
        in>>type>>x>>y;

        if(type == 0){
            costt[x] = y;
            myaint.update(1, 1, n, wherenodeidx[x]);
        }else{
            out<<hldquery(x, y)<<"\n";
        }
    }

    return 0;
}