Cod sursa(job #2300651)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 11 decembrie 2018 20:51:57
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.87 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#define DIMN 100001
using namespace std;
int lnt,nrc;
int d[DIMN],l[DIMN],poz[DIMN],up[DIMN],f[DIMN],val[DIMN],lvl[DIMN];
vector <int> v[DIMN],w[DIMN],aint[DIMN];
void precalc (int nod){
    int i,vecin;
    d[nod]=1;
    f[nod]=1;
    for (i=0;i<v[nod].size();i++){
        vecin=v[nod][i];
        if (!f[vecin]){
            precalc (vecin);
            d[nod]+=d[vecin];
            lvl[vecin]=1+lvl[nod];
        }
    }
}
void dfs_lant(int nod,int tata){
    int i,vecin,ok=0,maxi,fiu;
    maxi=0;
    fiu=0;
    for (i=0;i<v[nod].size();i++){
        vecin=v[nod][i];
        if (vecin!=tata){
            ok=1;
            dfs_lant(vecin,nod);
            if (d[vecin]>maxi){
                maxi=d[vecin];
                fiu=vecin;
            }
        }
    }
    if (!ok){ /// frunza
        lnt++;
        l[nod]=lnt; /// lantul din care apartine
        w[lnt].push_back(nod);
    }else { /// unim cu poz
        w[l[fiu]].push_back(nod);
        l[nod]=l[fiu];
        for (i=0;i<v[nod].size();i++){
            vecin=v[nod][i];
            if (vecin!=tata && vecin!=fiu)
                up[l[vecin]]=nod; /// din lantul vecinului trecem in lantul nodului
        }
    }
}
void build_aint (int lant,int p,int st,int dr){
    int mid;
    if (st==dr){
        aint[lant][p]=val[w[lant][nrc]];
        nrc++;
        return;
    }
    mid=(st+dr)/2;
    build_aint(lant,2*p,st,mid);
    build_aint(lant,2*p+1,mid+1,dr);
    aint[lant][p]=max(aint[lant][2*p],aint[lant][2*p+1]);
}
void update (int lant,int p,int st,int dr,int pf){
    int mid;
    if (st==dr){
        aint[lant][p]=val[w[lant][pf]];
        return;
    }
    mid=(st+dr)/2;
    if (pf<=mid)
        update(lant,2*p,st,mid,pf);
    else update(lant,2*p+1,mid+1,dr,pf);
    aint[lant][p]=max(aint[lant][2*p],aint[lant][2*p+1]);
}
int query_aint (int lant,int p,int st,int dr,int px,int py){
    int sol=0,mid;
    //if (lant==1 && px==1 && py==2)
      //  printf ("a");
    if (px<=st && dr<=py)
        return aint[lant][p];
    mid=(st+dr)/2;
    if (px<=mid)
        sol=max(sol,query_aint(lant,2*p,st,mid,px,py));
    if (mid+1<=py)
        sol=max(sol,query_aint(lant,2*p+1,mid+1,dr,px,py));
    return sol;
}
int query (int x,int y){
    if (l[x]!=l[y]){ /// avansam
        if (lvl[up[l[x]]]>lvl[up[l[y]]])
            return max(query(up[l[x]],y) , query_aint(l[x],1,0,w[l[x]].size()-1,0,poz[x]));
        else
            return max(query(x,up[l[y]]) , query_aint(l[y],1,0,w[l[y]].size()-1,0,poz[y]));
    }
    else return query_aint(l[x],1,0,w[l[x]].size()-1,min(poz[x],poz[y]),max(poz[x],poz[y]));
}
int main()
{
    FILE *fin=fopen ("heavypath.in","r");
    FILE *fout=fopen ("heavypath.out","w");
    int n,m,i,x,y,p,t,vecin;
    fscanf (fin,"%d%d",&n,&m);
    for (i=1;i<=n;i++){
        fscanf (fin,"%d",&val[i]);
    }
    for (i=1;i<n;i++){
        fscanf (fin,"%d%d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    precalc(1);
    /// imparte in lanturi
    dfs_lant (1,0);
    /// fiecare nod al catelea e
    for (i=1;i<=lnt;i++){
        reverse(w[i].begin(),w[i].end());
        p=0;
        for (vector <int> :: iterator j=w[i].begin();j!=w[i].end();j++){
            /// pozitia lui din lantul curent
            vecin=*j;
            //printf ("%d ",vecin);
            poz[vecin]=p;
            p++;
        }
        //printf ("\n");
    }
    for (i=1;i<=lnt;i++){
        aint[i].resize(w[i].size()*4);
        nrc=0;
        build_aint(i,1,0,w[i].size()-1);
    }
    for (;m;m--){
        fscanf (fin,"%d%d%d",&t,&x,&y);
        if (t==0){
            val[x]=y;
            update (l[x],1,0,w[l[x]].size()-1,poz[x]);
        }
        else
            fprintf (fout,"%d\n",query (x,y));
    }
    return 0;
}