Cod sursa(job #1240292)

Utilizator sebinechitasebi nechita sebinechita Data 10 octombrie 2014 22:56:45
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.27 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
#define MAX 100010

typedef vector <int> :: iterator iter;
vector <int> G[MAX];
vector <int> P[MAX];
int viz[MAX], w[MAX], d[MAX], path[MAX], decalaj[MAX], a[MAX], dad[MAX], Pdad[MAX], indice[MAX], aint[4*MAX];
int dr, val, ind, n, l, r;

void dfs(int nod)
{
    viz[nod]=1;
    w[nod]=1;
    int fr, mw, ind;
    fr=1;
    mw=-1;
    ind=0;
    for(iter it=G[nod].begin();it!=G[nod].end();it++)
    {
        if(viz[*it])
            continue;
        fr=0;
        d[*it]=d[nod]+1;
        dfs(*it);
        dad[*it]=nod;
        Pdad[path[*it]]=nod;
        w[nod]+=w[*it];
        if(w[*it]>mw)
        {
            mw=w[*it];
            ind=*it;
        }
    }
    if(fr)
    {
        path[nod]=++dr;
        P[dr].push_back(nod);
        return;
    }
    path[nod]=path[ind];
    P[path[nod]].push_back(nod);
}

void build(int nod, int st, int dr, int dec, int ind)
{
    if(st==dr)
    {
        aint[nod+dec]=a[P[ind][st-1]];
        return;
    }
    int mij=(st+dr)>>1;
    build(2*nod, st, mij, dec, ind);
    build(2*nod+1, mij+1, dr, dec, ind);
    aint[nod+dec]=max(aint[2*nod+dec], aint[2*nod+1+dec]);
}

void do_path()
{
    d[1]=1;
    dfs(1);
    for(int i=1;i<=dr;i++)
    {
        reverse(P[i].begin(), P[i].end());
        decalaj[i]=decalaj[i-1]+4*P[i-1].size();
        build(1, 1, P[i].size(), decalaj[i], i);
        for(int j=0;j<P[i].size();j++)
            indice[P[i][j]]=j+1;
    }
}

void update(int nod, int st, int dr, int dec)
{
    if(st==dr)
    {
        aint[nod+dec]=val;
        return;
    }
    int mij=(st+dr)>>1;
    if(ind<=mij)
        update(2*nod, st, mij, dec);
    else
        update(2*nod+1, mij+1, dr, dec);
    aint[nod+dec]=max(aint[2*nod+dec], aint[2*nod+1+dec]);
}

int query(int nod, int st, int dr, int dec)
{
    if(l<=st && dr<=r)
        return aint[nod+dec];
    int mij=(st+dr)>>1, rez=0;
    if(l<=mij)
        rez=max(rez, query(2*nod, st, mij, dec));
    if(mij+1<=r)
        rez=max(rez, query(2*nod+1, mij+1, dr, dec));
    return rez;
}

int main()
{
    int m, i, x, y, t;
    fin>>n>>m;
    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);
    }
    do_path();
    Pdad[path[1]]=0;
    while(m--)
    {
        fin>>t>>x>>y;
        if(t==0)
        {
            ind=indice[x];
            val=y;
            a[x]=y;
            update(1, 1, P[path[x]].size(), decalaj[path[x]]);
        }
        else
        {
            int rez=0;
            while(path[x]!=path[y])
            {
                if(d[Pdad[path[x]]]<d[Pdad[path[y]]])
                    swap(x, y);
                l=1;
                r=indice[x];
                rez=max(rez, query(1, 1, P[path[x]].size(), decalaj[path[x]]));
                x=Pdad[path[x]];
            }
            if(d[x]>d[y])
                swap(x, y);
            l=indice[x];
            r=indice[y];
            rez=max(rez, query(1, 1, P[path[x]].size(), decalaj[path[x]]));
            fout<<rez<<"\n";
        }
    }
}