Cod sursa(job #1472725)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 17 august 2015 17:08:40
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int i,a,b,t,x,y,N,M,nL,sol,v[100005],fol[100005],niv[100005],l[100005],aint[400020],lTata[100005],lNiv[100005],lDim[100005],lPoz[100005],w[100005];
vector<int> G[100005],P[100005];
void df(int nod) {
    fol[nod]=w[nod]=1;
    int frunza=1,lN=-1;
    for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
    if(!fol[*it]) {
        frunza=0,niv[*it]=niv[nod]+1,df(*it),w[nod]+=w[*it];
        if(lN==-1||w[*it]>w[lN])
            lN=*it;
    }
    if(frunza) {
        l[nod]=++nL,lDim[nL]=1,P[nL].push_back(nod);
        return;
    }
    l[nod]=l[lN],lDim[l[nod]]++,P[l[nod]].push_back(nod);
    for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
    if(*it!=lN&&niv[*it]>=niv[nod])
        lTata[l[*it]]=nod,lNiv[l[*it]]=niv[nod];
}
void build(int nod,int left,int right,int decalaj,int lant) {
    if(left==right) {
        aint[nod+decalaj]=v[P[lant][left-1]];
        return;
    }
    int med=(left+right)/2;
    build(nod*2,left,med,decalaj,lant),build(nod*2+1,med+1,right,decalaj,lant),aint[nod+decalaj]=max(aint[nod*2+decalaj],aint[nod*2+1+decalaj]);
}
void update(int nod,int left,int right,int poz,int val,int decalaj) {
    if(left==right) {
        aint[nod+decalaj]=val;
        return;
    }
    int med=(left+right)/2;
    if(poz<=med)
        update(nod*2,left,med,poz,val,decalaj);
    else
        update(nod*2+1,med+1,right,poz,val,decalaj);
    aint[nod+decalaj]=max(aint[nod*2+decalaj],aint[nod*2+1+decalaj]);
}
int query(int nod,int left,int right,int qleft,int qright,int decalaj) {
    if(qleft<=left&&right<=qright)
        return aint[nod+decalaj];
    int med=(left+right)/2,rez=0;
    if(qleft<=med)
        rez=max(rez,query(nod*2,left,med,qleft,qright,decalaj));
    if(med<qright)
        rez=max(rez,query(nod*2+1,med+1,right,qleft,qright,decalaj));
    return rez;
}
int main() {
    freopen("heavypath.in","r",stdin),freopen("heavypath.out","w",stdout),scanf("%d%d",&N,&M);
    for(i=1;i<=N;++i)
        scanf("%d",&v[i]);
    for(i=1;i<N;++i)
        scanf("%d%d",&a,&b),G[a].push_back(b),G[b].push_back(a);
    niv[1]=1,df(1);
    for(i=1;i<=nL;++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);
    }
    while(M--) {
        scanf("%d%d%d",&t,&x,&y);
        if(!t)
            update(1,1,lDim[l[x]],niv[x]-lNiv[l[x]],y,lPoz[l[x]]);
        else {
            while(1) {
                if(l[x]==l[y]) {
                    if(niv[x]>niv[y])
                        swap(x,y);
                    sol=max(sol,query(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,query(1,1,lDim[l[x]],1,niv[x]-lNiv[l[x]],lPoz[l[x]])),x=lTata[l[x]];
            }
            printf("%d\n",sol),sol=0;
        }
    }
}