Cod sursa(job #1384999)

Utilizator RaduGabriel2012Dinu Radu RaduGabriel2012 Data 11 martie 2015 16:53:01
Problema Heavy Path Decomposition Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.57 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");

  vector <int> v[100005],lant[100005];

  int n,m,val[100005],nrn[100005],nrlant[100005],dad[100005],use[100005],niv[100005],k;
  int p[200005],pniv[200005],pos[200005],poslant[200005],nrp;
  int a[100005],px[100005],py[100005],ka,mxn=100003,qsol=0;
  int aint[400005];
  int lg[200005],rmq[200005][18];

 void DFS(int x,int lv)
 { int i,fiu=0,mx=0;
     use[x]=1; nrn[x]=1; niv[x]=lv;

       nrp++; pos[x]=nrp; p[nrp]=x; pniv[nrp]=lv;

     for(i=0;i<v[x].size();i++)
      if (!use[v[x][i]])
        {DFS(v[x][i],lv+1);

         nrp++; p[nrp]=x; pniv[nrp]=lv;

          nrn[x]+=nrn[v[x][i]];

         if (nrn[v[x][i]]>mx) {mx=nrn[v[x][i]]; fiu=v[x][i];}
        }

      if (nrn[x]==1) {k++; nrlant[x]=k; lant[k].push_back(x);}
       else
       { lant[nrlant[fiu]].push_back(x);
         nrlant[x]=nrlant[fiu];
       }

    for(i=0;i<v[x].size();i++)
     if (niv[x]<niv[v[x][i]] && nrlant[x]!=nrlant[v[x][i]])
       dad[nrlant[v[x][i]]]=x;
 }

 void RMQ()
 { int i,len,v1,v2;

    for(i=2;i<=nrp;i++)
     lg[i]=lg[i/2]+1;

     for(i=1;i<=nrp;i++)
      rmq[i][0]=p[i];

    for(len=1;len<=lg[nrp];len++)
     for(i=1;i<=nrp-(1<<len)+1;i++)
     { v1=rmq[i][len-1]; v2=rmq[i+(1<<(len-1))][len-1];

        if (niv[v1]<niv[v2]) rmq[i][len]=v1;
         else rmq[i][len]=v2;
     }
 }

 int LCA(int x,int y)
 { int p1=pos[x],p2=pos[y],len,v1,v2;

    if (p1>p2) swap(p1,p2);
     len=lg[p2-p1+1];

   v1=rmq[p1][len]; v2=rmq[p2-(1<<len)+1][len];

  if (niv[v1]<niv[v2]) return v1; else return v2;
 }

 void Update(int nod,int st,int dr,int pos,int val)
 { int mid=(st+dr)/2;
    if (st==dr) aint[nod]=val;
     else
     { if (pos<=mid) Update(2*nod,st,mid,pos,val);
         else Update(2*nod+1,mid+1,dr,pos,val);
        aint[nod]=max(aint[2*nod],aint[2*nod+1]);
     }
 }

 void Query(int nod,int st,int dr,int x,int y)
 {  int mid=(st+dr)/2;
   if (x<=st && dr<=y) qsol=max(qsol,aint[nod]);
    else
    { if (x<=mid) Query(2*nod,st,mid,x,y);
       if (y>mid) Query(2*nod+1,mid+1,dr,x,y);
    }
 }

 void BuildAint()
 { int i,pl;

    for(i=1;i<=k;i++)
    { px[i]=ka+1; pl=0;
       while(lant[i].size())
       { ka++; a[ka]=lant[i][lant[i].size()-1];
          pl++; poslant[a[ka]]=pl;
          Update(1,1,mxn,ka,val[a[ka]]);

         lant[i].pop_back();
       }
      py[i]=ka;

    }
 }

 int HeavyPath(int x,int y)
 { int i,p1,p2,res=0;
     if (niv[x]<niv[y]) swap(x,y);
     for(;;)
     {
       if (nrlant[x]==nrlant[y])
       { p1=poslant[x]; p2=poslant[y];

          if (p1>p2) swap(p1,p2);
          qsol=0;
          Query(1,1,mxn,px[nrlant[x]]+p1-1,px[nrlant[x]]+p2-1);
          return max(res,qsol);
       }
       else
       { p1=poslant[x];
           qsol=0;
          Query(1,1,mxn,px[nrlant[x]],px[nrlant[x]]+p1-1);
          res=max(res,qsol);
         x=dad[nrlant[x]];
       }
     }
 }

 int Ans(int x,int y)
 { return max(HeavyPath(x,LCA(x,y)),HeavyPath(LCA(x,y),y)); }

 int Upd(int x,int val)
 { int p1=poslant[x];
    Update(1,1,mxn,px[nrlant[x]]+p1-1,val);
 }

int main()
{ int i,t,x,y;
    f>>n>>m;

    for(i=1;i<=n;i++)
     f>>val[i];

    for(i=1;i<n;i++)
    { f>>x>>y;
       v[x].push_back(y);
       v[y].push_back(x);
    }

    DFS(1,1);
    RMQ();
    BuildAint();



   for(i=1;i<=m;i++)
   { f>>t>>x>>y;
      if (!t) Upd(x,y);
       else g<<Ans(x,y)<<"\n";
   }


    return 0;
}