Cod sursa(job #3269365)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 18 ianuarie 2025 19:52:56
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.64 kb
#include <bits/stdc++.h>

struct Lct
{
    struct Node
    {
        int ind,val,max,l,r,parent;
        bool rev;
        Node()
        {
            l=r=parent=-1;
            rev=false;
        }
    };
    std::vector<Node>node;
    void init(int n)
    {
        node.resize(n);
        for(int i=0;i<n;i++)
        {
            node[i].ind=i;
        }
    }
    bool is_root(const Node x)
    {
        int p=x.parent;
        return ((p==-1) || (node[p].l!=x.ind && node[p].r!=x.ind));
    }
    bool is_root(int x)
    {
        return is_root(node[x]);
    }
    void push_down(Node& x)
    {
        if(x.rev)
        {
            std::swap(x.l,x.r);
            x.rev=false;
            if(x.l!=-1)
            {
                node[x.l].rev^=true;
            }
            if(x.r!=-1)
            {
                node[x.r].rev^=true;
            }
        }
    }
    void recalc(int x)
    {
        node[x].max=node[x].val;
        if(node[x].l!=-1)
        {
            node[x].max=std::max(node[x].max , node[node[x].l].max);
        }
        if(node[x].r!=-1)
        {
            node[x].max=std::max(node[x].max , node[node[x].r].max);
        }
    }
    void push_down(int x)
    {
        push_down(node[x]);
    }
    void rotate(int x)
    {
        Node& now=node[x];
        Node& p=node[now.parent];
        push_down(p);
        push_down(now);
        now.parent=p.parent;
        if(!is_root(p))
        {
            Node& gp=node[p.parent];
            if(gp.l==p.ind)
            {
                gp.l=x;
            }
            else if(gp.r==p.ind)
            {
                gp.r=x;
            }
            else
            {
                assert(false);
            }
        }
        if(p.l==now.ind)
        {
            p.l=now.r;
            now.r=p.ind;
            if(p.l!=-1)
            {
                node[p.l].parent=p.ind;
            }
        }
        else if(p.r==now.ind)
        {
            p.r=now.l;
            now.l=p.ind;
            if(p.r!=-1)
            {
                node[p.r].parent=p.ind;
            }
        }
        else
        {
            assert(false);
        }
        p.parent=now.ind;
        recalc(p.ind);
        recalc(now.ind);
    }
    void splay(int v)
    {
        while(!is_root(v))
        {
            Node& now=node[v];
            Node& p=node[now.parent];
            if(!is_root(p))
            {
            	Node& gp=node[p.parent];
                if((gp.r==p.ind) == (p.r==now.ind))
                {
                    rotate(p.ind);
                }
                else
                {
                    rotate(v);
                }
            }
            rotate(v);
        }
        push_down(v);
    }
    void access(int v)
    {
        int last=-1;
        for(int it=v;it!=-1;it=node[it].parent)
        {
            splay(it);
            node[it].r=last;
            last=it;
            recalc(it);
        }
        splay(v);
        recalc(v);
    }
    void make_root(int v)
    {
        access(v);
        if(node[v].l!=-1)
        {
            node[node[v].l].rev^=true;
        }
        node[v].l=-1;
        recalc(v);
    }
    void link(int x,int y)
    {
        make_root(y);
        node[y].parent=x;
    }
    /*void cut(int x,int y)
    {
        make_root(x);
        access(y);
        if(node[y].l==x)
        {
            node[y].l=-1;
            node[x].parent=-1;
            recalc(y);
        }
    }*/
    bool connected(int x,int y)
    {
        access(x);
        access(y);
        return node[x].parent!=-1;
    }
    void set_val(int x,int val)
    {
        make_root(x);
        node[x].val=val;
        recalc(x);
    }
    int query(int x,int y)
    {
        make_root(x);
        access(y);
        return node[y].max;
    }
};
using namespace std;
int main()
{
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,q;
    cin>>n>>q;
    Lct lc;
    lc.init(n);
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        lc.set_val(i,x);
    }
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        x--;
        y--;
        lc.link(x,y);
    }
    while(q--)
    {
        int cer,x,y;
        cin>>cer>>x>>y;
        if(cer==0)
        {
            x--;
            lc.set_val(x,y);
        }
        else
        {
            x--;
            y--;
            cout<<lc.query(x,y)<<'\n';
        }
    }
}