Cod sursa(job #2762737)

Utilizator betybety bety bety Data 9 iulie 2021 14:33:47
Problema Heavy Path Decomposition Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.07 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
int n,q,x,y,t,temp;
const int lim=1e5+3;
vector<int> vec[lim];
int papa[lim];
int val[lim];
int urm[lim];
int dp[lim];
int ad[lim];
bool ok[lim];
void df(int nod,int add)
{
    ad[nod]=add;
    ok[nod]=true;
    int maxim=-1;
    for(int x:vec[nod])
    if(!ok[x])
    {
        df(x,add+1);
        papa[x]=nod;
        dp[nod]+=dp[x];
        if(dp[x]>maxim)
            maxim=dp[x],
            urm[nod]=x;
    }
}
int unde[lim];
struct path
{
    int tata;
    vector<int> tree;
    vector<int> nodes;
    path(int nod)
    {
        tata=nod;
        nodes.clear();
        nodes.push_back(0);
    }
    void init()
    {
        tree.clear();
        tree.resize(4*nodes.size());
    }
    void build(int nod,int l,int r)
    {
        if(l==r)
        {
            tree[nod]=nodes[l];
            return ;
        }
        int med=(l+r)>>1;
        build(2*nod,l,med);
        build(2*nod+1,med+1,r);
        tree[nod]=max(tree[2*nod],tree[2*nod+1]);
    }
    void update(int nod,int l,int r,int poz,int vxl)
    {
        if(l==r)
        {
            tree[nod]=vxl;
            return ;
        }
        int med=(l+r)>>1;
        if(poz<=med) update(2*nod,l,med,poz,vxl);
        else update(2*nod+1,med+1,r,poz,vxl);
        tree[nod]=max(tree[2*nod],tree[2*nod+1]);
    }
    int query(int nod,int l,int r,int a,int b)
    {
        if(a<=l and r<=b)
            return tree[nod];
        int med=(l+r)>>1;
        int ans1=0,ans2=0;
        if(a<=med) ans1=query(2*nod,l,med,a,b);
        if(b>med) ans2=query(2*nod+1,med+1,r,a,b);
        return max(ans1,ans2);
    }
};
path* buc[lim];
int nr[lim],cnt;
void make(int nod,int nrp)
{
    nr[nod]=nrp;
    path* p=buc[nrp];
    unde[nod]=p->nodes.size();
    p->nodes.push_back(val[nod]);
    if(urm[nod]==0)
    {
        p->init();
        p->build(1,1,p->nodes.size()-1);
        return ;
    }
    make(urm[nod],nrp);
    for(int x:vec[nod])
    if(x!=papa[nod] and x!=urm[nod])
    {
        ++cnt;
        buc[cnt]=new path(x);
        make(x,cnt);
    }
}
int dmax(int x,int y)
{
    int ans=0;
    while(nr[x]!=nr[y])
    {
        if(ad[buc[nr[x]]->tata]<ad[buc[nr[y]]->tata]) swap(x,y);
        ans=max(ans,buc[nr[x]]->query(1,1,buc[nr[x]]->nodes.size()-1,1,unde[x]));
        x=papa[buc[nr[x]]->tata];
    }
    int jos=max(unde[x],unde[y]);
    int sus=min(unde[x],unde[y]);
    ans=max(ans,buc[nr[x]]->query(1,1,buc[nr[x]]->nodes.size()-1,sus,jos));
    return ans;
}
int main()
{
    in>>n>>q;
    for(int i=1;i<=n;++i)
        in>>val[i];
    for(int i=1;i<n;++i)
    {
        in>>x>>y;
        vec[x].push_back(y);
        vec[y].push_back(x);
    }
    df(1,1);
    cnt=1;
    buc[1]=new path(1);
    make(1,1);
    for(int i=1;i<=q;++i)
    {
        in>>t>>x>>y;
        if(t==0)
            buc[nr[x]]->update(1,1,buc[nr[x]]->nodes.size()-1,unde[x],y);
        else out<<dmax(x,y)<<'\n';
    }
    return 0;
}