Cod sursa(job #2839250)

Utilizator alexdumitruAlexandru Dumitru alexdumitru Data 25 ianuarie 2022 17:15:35
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int NMAX=1e5+5;

vector<int> g[NMAX];

int mymax(int a, int b)
{
    return (a>b?a:b);
}

int mymin(int a, int b)
{
    return (a<b?a:b);
}

void myswap(int &a, int &b)
{
    int c=a;
    a=b;
    b=c;
}

int n,m,i,t,x,y,q;
int a[NMAX];
int level[NMAX];
int father[NMAX];
int pos[NMAX];
int w[NMAX];
int ms[NMAX];
int id[NMAX];
int sl[NMAX];
int first[NMAX];

int cnt=1;

class segtree{
    int *a;
public:
    void construct(int sz)
    {
        sz<<=2;
        a = new int [sz+5];
        for(int i=1;i<=sz;i++)
            a[i]=0;
    }
    void update(int nod, int st, int dr, int poz, int v)
    {
        if(st==dr)
        {
            a[nod]=v;
            return;
        }
        int m=(st+dr)>>1;
        if(poz<=m)update(nod<<1,st,m,poz,v);
        else update((nod<<1)|1,m+1,dr,poz,v);
        a[nod]=mymax(a[nod<<1],a[(nod<<1|1)]);
    }
    int query(int nod, int st, int dr, int l, int r)
    {
        if(st>dr)return 0;
        if(l<=st&&dr<=r)
            return a[nod];
        int s1=0,s2=0,m=(st+dr)>>1;
        if(l<=m)s1=query(nod<<1,st,m,l,r);
        if(m<r)s2=query((nod<<1)|1,m+1,dr,l,r);
        return mymax(s1,s2);
    }
} aint[NMAX];


void Find(int nod=1, int dad=0, int lvl=1)
{
    w[nod]=1;
    father[nod]=dad;
    level[nod]=lvl;
    for(auto it:g[nod])
        if(it!=dad)
        {
            Find(it,nod,lvl+1);
            w[nod]+=w[it];
            if(w[it]>w[ms[nod]])
                ms[nod]=it;
        }
}

void dfs(int nod=1, int dad=0)
{
    id[nod]=cnt;
    pos[nod]=++sl[cnt];
    if(pos[nod]==1)
        first[cnt]=nod;
    if(ms[nod])
        dfs(ms[nod],nod);
    for(auto it:g[nod])
        if(it!=dad&&it!=ms[nod])
        {
            cnt++;
            dfs(it,nod);
        }
}

int Query(int x, int y)
{
    if(id[x]==id[y])
        return aint[id[x]].query(1,1,sl[id[x]],mymin(pos[x],pos[y]),mymax(pos[x],pos[y]));
    if(level[first[id[x]]]>level[first[id[y]]])
        myswap(x,y);
    return mymax(Query(y,first[id[y]]),Query(x,father[first[id[y]]]));
}

int main()
{
    fin>>n>>q;
    for(i=1;i<=n;i++)
        fin>>a[i];
    for(i=1;i<n;i++)
    {
        fin>>x>>y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    Find();
    dfs();
    for(i=1;i<=cnt;i++)
        aint[i].construct(sl[i]);
    for(int i=1;i<=n;i++)
        aint[id[i]].update(1,1,sl[id[i]],pos[i],a[i]);
    while(q--)
    {
        fin>>t>>x>>y;
        if(t==0)
            aint[id[x]].update(1,1,sl[id[x]],pos[x],y);
        else fout<<Query(x,y)<<'\n';
    }
    return 0;
}