Cod sursa(job #940684)

Utilizator stefanzzzStefan Popa stefanzzz Data 16 aprilie 2013 22:00:31
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.52 kb
#include <fstream>
#include <vector>
#define MAXN 100005
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");

struct arbi{
    int val[4*MAXN];};

int t,n,m,v[MAXN],tata[MAXN],tatal[MAXN],x,y,xx,lant[MAXN],pozlant[MAXN],poz,nrl,lvl[MAXN],mxq,ls,ld,mxai,aux2;
vector<int> G[MAXN],lanturi[MAXN],vlanturi[MAXN];
vector<arbi> arb;
arbi aux;

int MAX(int a,int b);
void DFS(int p);
void build_ai(int nod,int st,int dr);
void update_ai(int nod,int st,int dr);
void query(int a,int b);
void query_ai(int nod,int st,int dr);

int main()
{
    int i,j;
    f>>n>>m;
    for(i=1;i<=n;i++)
        f>>v[i];
    for(i=1;i<n;i++){
        f>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);}
    tata[1]=-1;
    lvl[1]=1;
    DFS(1);
    arb.push_back(aux);
    for(i=1;i<=nrl;i++){
        for(j=lanturi[i].size()-1;j>=0;j--){
            x=lanturi[i][j];
            vlanturi[i].push_back(v[x]);
            pozlant[x]=vlanturi[i].size()-1;}
        x=i;
        build_ai(1,0,lanturi[i].size()-1);
        arb.push_back(aux);}
    for(i=1;i<=m;i++){
        f>>t>>x>>y;
        if(t){
            mxq=0;
            query(x,y);
            g<<mxq<<'\n';}
        else{
            xx=lant[x];
            poz=pozlant[x];
            update_ai(1,0,lanturi[xx].size()-1);}}
    f.close();
    g.close();
    return 0;
}

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

void DFS(int p){
    int i,mx=0,mxi;
    if(G[p].size()==1&&tata[p]!=-1){
        lanturi[++nrl].push_back(p);
        lant[p]=nrl;
        return;}
    for(i=0;i<G[p].size();i++){
        x=G[p][i];
        if(!tata[x]){
            lvl[x]=lvl[p]+1;
            tata[x]=p;
            DFS(x);
            x=G[p][i];
            if(lanturi[lant[x]].size()>mx){
                mx=lanturi[lant[x]].size();
                mxi=i;}}}
    for(i=0;i<G[p].size();i++){
        if(i==mxi||tata[p]==G[p][i])
            continue;
        tatal[lant[G[p][i]]]=p;}
    lanturi[lant[G[p][mxi]]].push_back(p);
    lant[p]=lant[G[p][mxi]];}

void build_ai(int nod,int st,int dr){
    int mij;
    if(st==dr){
        aux.val[nod]=vlanturi[x][st];
        return;}
    mij=(st+dr)/2;
    build_ai(2*nod,st,mij);
    build_ai(2*nod+1,mij+1,dr);
    aux.val[nod]=MAX(aux.val[2*nod],aux.val[2*nod+1]);}

void update_ai(int nod,int st,int dr){
    int mij;
    if(st==dr){
        arb[xx].val[nod]=y;
        return;}
    mij=(st+dr)/2;
    if(poz<=mij)
        update_ai(2*nod,st,mij);
    else
        update_ai(2*nod+1,mij+1,dr);
    arb[xx].val[nod]=MAX(arb[xx].val[2*nod],arb[xx].val[2*nod+1]);}

void query_ai(int nod,int st,int dr){
    int mij;
    if(st>=ls&&dr<=ld){
        if(arb[x].val[nod]>mxai)
            mxai=arb[x].val[nod];
        return;}
    mij=(st+dr)/2;
    if(ls<=mij)
        query_ai(2*nod,st,mij);
    if(ld>mij)
        query_ai(2*nod+1,mij+1,dr);}

void query(int a,int b){
    if(lant[a]==lant[b]){
        x=lant[a];
        if(pozlant[a]>pozlant[b]){
            ls=pozlant[b];
            ld=pozlant[a];}
        else{
            ls=pozlant[a];
            ld=pozlant[b];}
        mxai=0;
        query_ai(1,0,lanturi[x].size()-1);
        if(mxai>mxq)
            mxq=mxai;
        return;}
    if(lvl[tatal[lant[a]]]<lvl[tatal[lant[b]]]){
        aux2=a;
        a=b;
        b=aux2;}
    x=lant[a];
    mxai=0;
    ls=0;
    ld=pozlant[a];
    query_ai(1,0,lanturi[x].size()-1);
    if(mxai>mxq)
        mxq=mxai;
    query(tatal[x],b);}