Cod sursa(job #1385021)

Utilizator RaduGabriel2012Dinu Radu RaduGabriel2012 Data 11 martie 2015 17:09:39
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 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],ka,mxn=100003,qsol=0;
  int aint[400005];

 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 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();
       }


    }
 }

 int Ans(int x,int y)
 { int i,p1,p2,res=0;

     for(;;)
     {
         if (niv[dad[nrlant[x]]]<niv[dad[nrlant[y]]]) swap(x,y);

       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 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);
    BuildAint();

 //cout<<Ans(4,7);

   for(i=1;i<=m;i++)
   { f>>t>>x>>y;

      if (!t) Upd(x,y);
       else g<<Ans(x,y)<<"\n";
   }


    return 0;
}