Cod sursa(job #2770454)

Utilizator mjmilan11Mujdar Milan mjmilan11 Data 21 august 2021 00:55:17
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.69 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int NMAX = 100005;
int a[NMAX],nivel[NMAX],parent[NMAX],arb_dim[NMAX],decalare[NMAX],aint[4*NMAX];
int nr_lanturi,ind_lant[NMAX],parinte_lant[NMAX],pozitia_in_lant[NMAX];
vector <int> v[NMAX],lant[NMAX];
int operatie,x,y,n,m;
bool ver[NMAX];
void dfs(int node,int niv,int p){
    ver[node]=true;
    nivel[node]=niv;
    parent[node]=p;
    arb_dim[node]=1;
    int max_node=0,max_dim=0;
    for(int i=0;i<v[node].size();i++){
        int vecin=v[node][i];
        if(ver[vecin]==true) continue;
        dfs(vecin,niv+1,node);
        arb_dim[node]+=arb_dim[vecin];
        if(arb_dim[vecin]>max_dim){
            max_dim=arb_dim[vecin];
            max_node=vecin;
        }
    }
    if(max_dim==0){
        lant[++nr_lanturi].push_back(node);
        ind_lant[node]=nr_lanturi;
        parinte_lant[nr_lanturi]=parent[node];
    } else {
        int ind=ind_lant[max_node];
        lant[ind].push_back(node);
        ind_lant[node]=ind;
        parinte_lant[ind]=parent[node];
    }
}
void update(int node,int st,int dr,int poz,int val,int decalare){
    if(st>dr) return;
    if(st==dr and st==poz){
        aint[node+decalare]=val;
        return;
    }
    int mij=(st+dr)/2;
    if(poz<=mij) update(2*node,st,mij,poz,val,decalare);
    else         update(2*node+1,mij+1,dr,poz,val,decalare);
    aint[node+decalare]=max(aint[2*node+decalare],aint[2*node+1+decalare]);
}
int query(int node,int st,int dr,int qst,int qdr,int decalare){
    if(qst<=st and dr<=qdr){
        return aint[node+decalare];
    }
    int mij=(st+dr)/2;
    int x=0,y=0;
    if(qst<=mij) x=query(2*node,st,mij,qst,qdr,decalare);
    if(qdr>mij)  y=query(2*node+1,mij+1,dr,qst,qdr,decalare);
    return max(x,y);
}
int main()
{
    fin >> n >> m;
    for(int i=1;i<=n;i++) fin >> a[i];
    for(int i=1;i<n;i++){
        fin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,1,0);
    for(int i=1;i<=nr_lanturi;i++){
        decalare[i]=decalare[i-1]+4*lant[i-1].size();
        int st=0,dr=lant[i].size()-1;
        while(st<dr){
            swap(lant[i][st],lant[i][dr]);
            pozitia_in_lant[lant[i][st]]=st;
            pozitia_in_lant[lant[i][dr]]=dr;
            st++;
            dr--;
        }
        pozitia_in_lant[lant[i][st]]=st;
    }
    for(int i=1;i<=n;i++) update(1,0,lant[ind_lant[i]].size()-1,pozitia_in_lant[i],a[i],decalare[ind_lant[i]]);
    for(int i=1;i<=m;i++){
        fin >> operatie >> x >> y;
        if(operatie==0){
            update(1,0,lant[ind_lant[x]].size()-1,pozitia_in_lant[x],y,decalare[ind_lant[x]]);
            continue;
        }
        int rasp=0;
        bool ok=true;
        while(ok==true){
            int lant1=ind_lant[x];
            int lant2=ind_lant[y];
            if(lant1==lant2){
                int poz1=pozitia_in_lant[x];
                int poz2=pozitia_in_lant[y];
                if(poz1>poz2) swap(poz1,poz2);
                rasp=max(rasp,query(1,0,lant[lant1].size()-1,poz1,poz2,decalare[lant1]));
                ok=false;
                break;
            } else if(nivel[parinte_lant[lant1]]>nivel[parinte_lant[lant2]]){
                int poz=pozitia_in_lant[x];
                rasp=max(rasp,query(1,0,lant[lant1].size()-1,0,poz,decalare[lant1]));
                x=parinte_lant[lant1];
            } else {
                int poz=pozitia_in_lant[y];
                rasp=max(rasp,query(1,0,lant[lant2].size()-1,0,poz,decalare[lant2]));
                y=parinte_lant[lant2];
            }
        }
        fout << rasp << '\n';
    }
    return 0;
}