Cod sursa(job #1166615)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 3 aprilie 2014 18:33:25
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int nmax = 100005;
int n,m,val[nmax],i,x,y,subarb[nmax],lev[nmax],f[nmax],poz[nmax],lant[nmax],paths,Poz,Val,a,b,sol;
vector<int> v[nmax],p[nmax],arb[nmax];
void dfs(int x,int t)
{
    subarb[x]=1;
    for(vector<int>::iterator it=v[x].begin();it!=v[x].end();it++)
        if(*it!=t)
        {
            f[*it]=x;
            lev[*it]=lev[x]+1;
            dfs(*it,x);
            subarb[x]+=subarb[*it];
        }
    if(v[x].size()==1 && x!=1)
    {
        lant[x]=++paths;
        p[paths].push_back(0);
        p[paths].push_back(x);
        poz[x]=1;
        return;
    }
    int maxs=0;
    for(vector<int>::iterator it=v[x].begin();it!=v[x].end();it++)
        if(*it!=t && subarb[*it]>subarb[maxs]) maxs=*it;
    lant[x]=lant[maxs];
    p[lant[x]].push_back(x);
    poz[x]=p[lant[x]].size()-1;
}
void build(int node,int l,int r,int path)
{
    if(l==r) {arb[path][node]=val[p[path][l]]; return;}
    int m=(l+r)/2;
    int ls=2*node;
    int rs=ls+1;
    build(ls,l,m,path);
    build(rs,m+1,r,path);
    arb[path][node]=max(arb[path][ls],arb[path][rs]);
}
void update(int node,int l,int r,int path)
{
    if(l==r) {arb[path][node]=Val; return;}
    int m=(l+r)/2;
    int ls=2*node;
    int rs=ls+1;
    if(Poz<=m) update(ls,l,m,path);
    else update(rs,m+1,r,path);
    arb[path][node]=max(arb[path][ls],arb[path][rs]);
}
void query(int node,int l,int r,int path)
{
    if(l>=a && r<=b) {sol=max(sol,arb[path][node]); return;}
    int m=(l+r)/2;
    int ls=2*node;
    int rs=ls+1;
    if(a<=m) query(ls,l,m,path);
    if(b>m) query(rs,m+1,r,path);
}
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",&val[i]);
	for(i=1;i<n;i++)
	{
	    scanf("%d%d",&x,&y);
	    v[x].push_back(y);
	    v[y].push_back(x);
	}
	lev[1]=1; dfs(1,0);
	for(i=1;i<=paths;i++)
	{
	    reverse(p[i].begin()+1,p[i].end());
	    arb[i].resize(4*p[i].size()+5);
	    build(1,1,p[i].size()-1,i);
	}
	for(i=1;i<=n;i++) poz[i]=p[lant[i]].size()-poz[i];
	for(;m;m--)
	{
	    scanf("%d%d%d",&i,&x,&y);
	    if(i==0)
	    {
	        Poz=poz[x]; Val=y;
	        update(1,1,p[lant[x]].size()-1,lant[x]);
	    }
	    else
	    {
	        sol=0;
	        for(;;)
	        {
	            if(lant[x]==lant[y])
	            {
	                a=min(poz[x],poz[y]);
	                b=max(poz[x],poz[y]);
	                query(1,1,p[lant[x]].size()-1,lant[x]);
	                break;
	            }
	            if(lev[p[lant[x]][1]]<lev[p[lant[y]][1]]) swap(x,y);
	            a=1; b=poz[x]; query(1,1,p[lant[x]].size()-1,lant[x]);
	            x=f[p[lant[x]][1]];
	        }
	        printf("%d\n",sol);
	    }
	}
	return 0;
}