Cod sursa(job #940783)

Utilizator costyv87Vlad Costin costyv87 Data 17 aprilie 2013 02:56:38
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.67 kb
//HighFlow
#include <cstdio>
#include <vector>
#define fcat(c) while (c!='\n') fscanf(f,"%c",&c)
#define cat(c) while (c!='\n') scanf("%c",&c)
#define For(i,st,dr,k) for (int i=(st);i<=(dr);i+=(k))
#define ll (long long)
#define kfl(i,j) (a[(i)][(j)].c-a[(i)][(j)].f)
using namespace std;
FILE *f,*g;
vector <int> a[100100];
vector <int> inv[100100];
vector <int> arb[100100];
int msk[100100]; // inversul lui inv
int con[100100]; // marimea fiecarui lant
int from[100100]; // pe ce lant e nodul curent
bool bf[100100];
bool lant[100100];
int tnod[100100];
int t[100100]; // indicele lantului tata al unui lant
int G[100100]; //greutatea
int ax[100100];
int lvl[100100];
int cn,n,m;
int i,j,left,right,x,y,tip,pos;

void read()
{
    int i,x,y;
    fscanf(f,"%d%d",&n,&m);

    for (i=1;i<=n;i++) fscanf(f,"%d",&ax[i]);
    for (i=1;i<n;i++)
    {
        fscanf(f,"%d%d",&x,&y);
        a[x].push_back(y);
        a[y].push_back(x);
    }
}


void pre_df(int x)
{
    int s=1,i;

    bf[x]=true;
    for (i=0;i<a[x].size();i++)
        if (!bf[a[x][i]])
        {
            pre_df(a[x][i]);
            s+=G[a[x][i]];
        }
    G[x]=s;
}

void elimina(int x)
{
    int i,mx,mxi;
    int k=1;

    while (1)
    {
        con[cn]=k;
        lant[x]=true;
        msk[x]=k;
        from[x]=cn;
        inv[cn].push_back(x);
        mx=-1;
        for (i=0;i<a[x].size();i++)
            if (mx<G[a[x][i]] && from[a[x][i]]==false)
            {
                mx=G[a[x][i]];
                mxi=a[x][i];
            }
        if (mx==-1) break;
        k++;
        x=mxi;
    }
}

void descompun(int x,int tata,int lv)
{
    int i;
    bf[x]=true;

    if (!lant[x])
    {
        inv[++cn].push_back(0);
        lvl[cn]=lv;
        tnod[x]=tata;
        t[cn]=from[tata];
        elimina(x);
        arb[cn].resize(con[cn]*5);
   }


    for (i=0;i<a[x].size();i++)
        if (!bf[a[x][i]])
            descompun(a[x][i],x,lv+1);
}

void update(int k,int nod,int st,int dr,int val)
{
    if (st==dr)
    {
        arb[k][nod]=val;
        return;
    }

    int m=(st+dr)/2;

    if (pos<=m)
        update(k,nod*2,st,m,val);
    else
        update(k,nod*2+1,m+1,dr,val);
    arb[k][nod]=max(arb[k][nod*2],arb[k][nod*2+1]);
}

int query(int k,int nod,int st,int dr)
{
    if (left<=st && dr<=right)
        return arb[k][nod];

    int m=(st+dr)/2;

    int r1=0,r2=0;

    if (left<=m) r1=query(k,nod*2,st,m);
    if (m<right) r2=query(k,nod*2+1,m+1,dr);
    return max(r1,r2);
}

int solve(int x,int y)
{
    int c1,c2,ans=0;

    c1=from[x];
    c2=from[y];

    while (c1!=c2)
        if (lvl[c1]>=lvl[c2])
        {
            left=1; right=msk[x];
            ans=max(ans,query(c1,1,1,con[c1]));
            x=tnod[inv[c1][1]]; c1=from[x];
        }
        else
        {
            left=1; right=msk[y];
            ans=max(ans,query(c2,1,1,con[c2]));
            y=tnod[inv[c2][1]]; c2=from[y];
        }

    left=min(msk[x],msk[y]); right=max(msk[x],msk[y]);
    ans=max(ans,query(c1,1,1,con[c1]));

    return ans;
}


int main()
{
    f=fopen("heavypath.in","r");
    g=fopen("heavypath.out","w");

    read();
    pre_df(1);
    for (i=1;i<=n;i++) bf[i]=false;
    descompun(1,0,1);

    for (i=1;i<=n;i++)
    {
        pos=msk[i];
        update(from[i],1,1,con[from[i]],ax[i]);
    }
    for (i=1;i<=m;i++)
    {
        fscanf(f,"%d%d%d",&tip,&x,&y);
        if (tip==0)
        {
            pos=msk[x];
            update(from[x],1,1,con[from[x]],y);
        }
        else
        {
            fprintf(g,"%d\n",solve(x,y));
        }
    }

	return 0;
}