Cod sursa(job #1656679)

Utilizator SilviuIIon Silviu SilviuI Data 19 martie 2016 17:59:30
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.76 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#define nmax 100010

using namespace std;

int n,m,tip,x,y,b;
int v[nmax],hight[nmax],w[nmax];
int szbucket[nmax],bucket[nmax],psbucket[nmax],tata[nmax];
vector <int> g[nmax],hp[nmax];

void dfs1(int nod,int dad)
{
    w[nod]=1;
    for (int i=0;i<(int)g[nod].size();i++)
        if (g[nod][i]!=dad) {
            hight[g[nod][i]]=hight[nod]+1;
            dfs1(g[nod][i],nod);
            w[nod]=w[nod]+w[g[nod][i]];
    }
}

void dfs2(int nod,int dad,int nrb)
{
    szbucket[nrb]++;
    bucket[nod]=nrb;
    psbucket[nod]=szbucket[nrb];
    int mx=0;
    for (int i=0;i<(int)g[nod].size();i++)
        if (w[mx]<w[g[nod][i]] && g[nod][i]!=dad) mx=g[nod][i];

    if (mx==0) return;

    dfs2(mx,nod,nrb);

    for (int i=0;i<(int)g[nod].size();i++)
        if (g[nod][i]!=dad && g[nod][i]!=mx) {
            b++; tata[b]=nod;
            dfs2(g[nod][i],nod,b);
    }

}

void update(int nod,int st,int dr,int pos,int val,vector <int> &t)
{
    if (st==dr) { t[nod]=val; return; } else
    {
        int m=(st+dr)/2;
        if (pos<=m) update(nod*2,st,m,pos,val,t); else
            update(nod*2+1,m+1,dr,pos,val,t);
        t[nod]=max(t[nod*2],t[nod*2+1]);
    }
}

int query(int nod,int st,int dr,int x,int y,vector <int> &t)
{
    if (st>=x && dr<=y) return t[nod]; else
    {
        int m=(st+dr)/2; int csol=0;

        if (x<=m) csol=max(csol,query(nod*2,st,m,x,y,t));
        if (y>m) csol=max(csol,query(nod*2+1,m+1,dr,x,y,t));

        return csol;
    }
}

int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);

    scanf("%d %d",&n,&m);

    for (int i=1;i<=n;i++) scanf("%d",&v[i]);

    for (int i=1;i<=n-1;i++) {
        scanf("%d %d",&x,&y);
        g[x].push_back(y); g[y].push_back(x);
    }

    b=1;

    dfs1(1,0);
    dfs2(1,0,1);

    for (int i=1;i<=b;i++) hp[i].resize(szbucket[i]*4);

    for (int i=1;i<=n;i++) update(1,1,szbucket[bucket[i]],psbucket[i],v[i],hp[bucket[i]]);

    //printtree(1,1,szbucket[1],hp[1]);

    for (int i=1;i<=m;i++) {

        scanf("%d %d %d",&tip,&x,&y);

        if (tip==0) update(1,1,szbucket[bucket[x]],psbucket[x],y,hp[bucket[x]]); else
        {
            int sol=0;

            while (bucket[x]!=bucket[y]) {

                if (hight[tata[bucket[x]]]<hight[tata[bucket[y]]]) swap(x,y);

                sol=max(sol,query(1,1,szbucket[bucket[x]],1,psbucket[x],hp[bucket[x]]));

                x=tata[bucket[x]];
            }

            if (psbucket[x]>psbucket[y]) swap(x,y);

            sol=max(sol,query(1,1,szbucket[bucket[x]],psbucket[x],psbucket[y],hp[bucket[x]]));

            printf("%d\n",sol);
        }

    }

    return 0;
}