Cod sursa(job #802092)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 25 octombrie 2012 20:28:45
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.83 kb
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define X 100001
int i,a,b,t,x,y,N,M,nL,sol,v[X],fol[X],niv[X],w[X],l[X],aint[4*X],lTata[X],lNiv[X],lDim[X],lPoz[X],q;
vector<int> G[X],P[X];

void df(int nod)
{fol[nod]=1;
int lN=-1,frunza=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);
    if(lN==-1||w[lN]<w[*it])
          lN=*it;}
if(frunza)
    {l[nod]=++nL,lDim[nL]=1,P[nL].push_back(nod);
    return;}
w[nod]=w[lN]+1,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),reverse(P[1].begin(),P[1].end()),build(1,1,lDim[1],lPoz[1],1);
for(i=2;i<=nL;++i)
    reverse(P[i].begin(),P[i].end()),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])
                              x^=y^=x^=y;
                      if(sol<(q=query(1,1,lDim[l[x]],niv[x]-lNiv[l[x]],niv[y]-lNiv[l[x]],lPoz[l[x]])))
                              sol=q;
                      break;}
                if(lNiv[l[x]]<lNiv[l[y]])
                      x^=y^=x^=y;
                if(sol<(q=query(1,1,lDim[l[x]],1,niv[x]-lNiv[l[x]],lPoz[l[x]])))
                      sol=q;
                x=lTata[l[x]];}
          printf("%d\n",sol),sol=0;}}
return 0;}