Cod sursa(job #1965175)

Utilizator trutruvasilicaHuhurez Marius trutruvasilica Data 13 aprilie 2017 23:50:42
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int Nmax=100010;
int N,M,nrL;
vector<int>G[Nmax],P[Nmax];
int v[Nmax],fol[Nmax],niv[Nmax],w[Nmax],l[Nmax],arb[4*Nmax];
int lTata[Nmax],lNiv[Nmax],lDim[Nmax],lPoz[Nmax];
struct operatie
{
    int t,x,y;
}op[Nmax];
void citire()
{
    int x,y;
    fin>>N>>M;
    for(int i=1;i<=N;i++) fin>>v[i];
    for(int i=1;i<N;i++)
    {
        fin>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    for(int i=1;i<=M;i++) fin>>op[i].t>>op[i].x>>op[i].y;
}
void dfs(int nod)
{
    w[nod]=1;
    fol[nod]=1;
    int hN=-1,frunza=1;
    for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();it++)
    {
        if(fol[*it]) continue;
        frunza=0;
        niv[*it]=niv[nod]+1;
        dfs(*it);
        w[nod]+=w[*it];

        if(hN==-1) hN=*it;
        else if(w[*it]>w[hN]) hN=*it;
    }

    if(frunza)
    {
        l[nod]=++nrL;
        lDim[nrL]=1;
        P[nrL].push_back(nod);
        return;
    }
    l[nod]=l[hN];
    lDim[l[nod]]++;
    P[l[nod]].push_back(nod);
    for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();it++)
    {
        if( *it==hN || niv[*it]<niv[nod]) continue;
        lTata[l[*it]]=nod;
        lNiv[l[*it]]=niv[nod];
    }
}
void build(int nod,int st,int dr,int decalaj,int lant)
{
    if(st==dr) arb[nod+decalaj]=v[P[lant][st-1]];
    else
    {
        int mid=(st+dr)/2;
        build(nod*2,st,mid,decalaj,lant);
        build(nod*2+1,mid+1,dr,decalaj,lant);

        arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
    }
}
void make_paths()
{
    niv[1]=1;
    dfs(1);
    for(int i=1;i<=nrL;i++)
    {
        reverse(P[i].begin(),P[i].end());
        if(i>1) lPoz[i]=lPoz[i-1]+lDim[i-1]*4;
        build(1,1,lDim[i],lPoz[i],i);
    }
}
void update(int nod,int st,int dr,int poz,int val,int decalaj)
{
    if(st==dr) arb[nod+decalaj]=val;
    else
    {
        int mid=(st+dr)/2;
        if(poz<=mid) update(nod*2,st,mid,poz,val,decalaj);
        else update(nod*2+1,mid+1,dr,poz,val,decalaj);
        arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
    }
}
int querry(int nod,int st,int dr,int a,int b,int decalaj)
{
    if(a<=st && b>=dr) return arb[nod+decalaj];
    else
    {
        int mid=(st+dr)/2,rez=0;
        if(a<=mid) rez=querry(nod*2,st,mid,a,b,decalaj);
        if(b>mid) rez=max(rez,querry(nod*2+1,mid+1,dr,a,b,decalaj));
        return rez;
    }
}
void solve()
{
    int t,x,y,sol=0;
    for(int i=1;i<=M;i++)
    {
        t=op[i].t;x=op[i].x;y=op[i].y;
        if(t==0) update(1,1,lDim[l[x]],niv[x]-lNiv[l[x]],y,lPoz[l[x]]);
        else
        {
            sol=0;
            while(1)
            {
                if(l[x]==l[y])
                {
                    if(niv[x]>niv[y]) swap(x,y);
                    sol=max(sol,querry(1,1,lDim[l[x]],niv[x]-lNiv[l[x]],niv[y]-lNiv[l[x]],lPoz[l[x]]));
                    break;
                }
                if(lNiv[l[x]]<lNiv[l[y]]) swap(x,y);

                sol=max(sol,querry(1,1,lDim[l[x]],1,niv[x]-lNiv[l[x]],lPoz[l[x]]));
                x=lTata[l[x]];
            }
            fout<<sol<<"\n";
        }
    }
}
int main()
{
    citire();
    make_paths();
    solve();
}