Cod sursa(job #3041929)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 2 aprilie 2023 19:40:24
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.43 kb
#include<fstream>
#include <vector>
using namespace std;
class AINT
{
    vector<int>aint;
    int update(int nod,int st,int dr,int l,int val)
    {
        if(st>l || dr<l)return aint[nod];
        if(st==dr)
        {
            aint[nod]=val;
        }
        else
        {
            int m=(st+dr>>1);
            aint[nod]=max(update(2*nod,st,m,l,val),update(2*nod+1,m+1,dr,l,val));
        }
        return aint[nod];
    }
    int query(int nod,int st,int dr,int l,int r)
    {
        if(st>r || dr<l)return 0;
        if(l<=st && dr<=r)
        {
            return aint[nod];
        }
        int m=(st+dr)/2;
        return max(query(2*nod,st,m,l,r),query(2*nod+1,m+1,dr,l,r));
    }
    int n;
public:
    AINT(int n)
    {
        this->n=n;
        aint=vector<int>(4*n+1,0);
    }
    int query(int st,int dr)
    {
        return query(1,0,n-1,st,dr);
    }
    void update(int st,int val)
    {
        aint[0]=update(1,0,n-1,st,val);
    }
    AINT(){};
};
class HEAVY
{
    AINT aint;
    vector<int>head,t,h,dp,poz;
    int n,acm=0;
    void dfs1(int nod,int tt,vector<vector<int>>&g)
    {
        t[nod]=tt;
        h[nod]=h[tt]+1;
        dp[nod]=1;
        for(auto &c:g[nod])
        {
            if(c!=tt)
            {
                dfs1(c,nod,g);
                dp[nod]+=dp[c];
            }
        }
    }
    void dfs2(int nod,int tt,int h,vector<vector<int>>&g)
    {
        poz[nod]=acm++;
        head[nod]=h;
        int val=-1;
        int maxx=-1;
        for(auto &c:g[nod])
        {
            if(c==tt)
            {
                continue;
            }
            if(val<dp[c])
            {
                val=dp[c];
                maxx=c;
            }
        }
        if(maxx==-1)return;
        dfs2(maxx,nod,h,g);
        for(auto &c:g[nod])
        {
            if(c==maxx || c==tt)continue;
            dfs2(c,nod,c,g);
        }
    }
    public:
    HEAVY(vector<vector<int>>&g)
    {
        n=(int)g.size();
        head=t=dp=poz=h=vector<int>(n);
        h[0]=0;
        dfs1(0,0,g);
        dfs2(0,0,0,g);
        aint=AINT(n);
    }
    void update(int x,int val)
    {
        aint.update(poz[x],val);
    }
    int query(int x,int y)
    {
        int rez=0;
        while(head[x]!=head[y])
        {
            if(h[head[x]]<h[head[y]])
            {
                swap(x,y);
            }
            rez=max(rez,aint.query(poz[head[x]],poz[x]));
            x=head[x];
            x=t[x];
        }
        rez=max(rez,aint.query(min(poz[y],poz[x]),max(poz[y],poz[x])));
        return rez;

    }
};


void  solve()
{
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    int n,q;
    cin>>n>>q;
    vector<int>a(n);
    for(auto &c:a)cin>>c;
    vector<vector<int>>g(n);
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        x--;y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    HEAVY tree(g);
    for(int i=0;i<n;i++)
    {
        tree.update(i,a[i]);
    }
    while(q--)
    {
        int tt,a,b;
        cin>>tt>>a>>b;
        if(!tt)
        {
            a--;
            tree.update(a,b);
        }
        else
        {
            a--;
            b--;
            cout<<tree.query(a,b)<<'\n';
        }
    }
}
int main()
{
    int tt=1;
    while(tt--)
    {
        solve();
    }
}