Cod sursa(job #1895695)

Utilizator pepsiM4A1Ozturk Arif pepsiM4A1 Data 28 februarie 2017 10:03:02
Problema Heavy Path Decomposition Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.11 kb
#include <cstdio>
#include <vector>
#define pb push_back
using namespace std;
const int nmax=1023;
int n,m;
vector<int>adj[nmax],arb[nmax];
int val[nmax],fre;
int weight[nmax],sze[nmax],chain[nmax],tata[nmax],root[nmax],niv[nmax],place_in_chain[nmax];
bool vis[nmax];
void dfs(int nod,int nivel)
{
    niv[nod]=nivel;
    weight[nod]=1;
    vis[nod]=1;
    vector<int>::iterator it;
    int maxim=0,which=0;
    for(it=adj[nod].begin();it!=adj[nod].end();++it)
    {
        if(vis[*it]) continue;
        tata[*it]=nod;
        dfs(*it,nivel+1);
        weight[nod]+=weight[*it];
        if(maxim<weight[*it])
        {
            maxim=weight[*it];
            which=*it;
        }
    }
    if(maxim==0)
    {
        chain[nod]=++fre;
        sze[chain[nod]]=1;
        place_in_chain[nod]=1;
        root[chain[nod]]=nod;
        return;
    }
    chain[nod]=chain[which];
    sze[chain[nod]]++;
    place_in_chain[nod]=place_in_chain[which]+1;
    root[chain[nod]]=nod;
}
void update(int pre,int st,int dr,int nod,int pos)
{
    if(st==dr) arb[pre][nod]=val[pos];
    else
    {
        int mij=(st+dr)/2;
        if(place_in_chain[pos]<=mij) update(pre,st,mij,2*nod,pos);
        else update(pre,mij+1,dr,2*nod+1,pos);
        arb[pre][nod]=max(arb[pre][2*nod],arb[pre][2*nod+1]);
    }
}
int query(int pre,int st,int dr,int p1,int p2,int nod)
{
    if(st==p1&&p2==dr) return arb[pre][nod];
    else
    {
        int mij=(st+dr)/2;
        if(p2<=mij) return query(pre,st,mij,p1,p2,2*nod);
        else if(p1>mij) return query(pre,mij+1,dr,p1,p2,2*nod+1);
        return max(query(pre,st,mij,p1,mij,2*nod),query(pre,mij+1,dr,mij+1,p2,2*nod+1));
    }
}
int main()
{
    freopen ("heavypath.in","r",stdin);
    freopen ("heavypath.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&val[i]);
    for(int i=1;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        adj[a].pb(b);
        adj[b].pb(a);
    }
    dfs(1,1);
    for(int i=1;i<=fre;i++) arb[i].resize(sze[i]*4);
    for(int i=1;i<=n;i++)
    {
        update(chain[i],1,sze[chain[i]],1,i);
    }
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        if(a==0)
        {
            val[b]=c;
            update(chain[b],1,sze[chain[b]],1,b);
        }
        else
        {
            int nb=niv[b],nc=niv[c],rasp=0;
            while(1)
            {
            //    printf("%d %d\n",b,c);
                if(chain[b]==chain[c])
                {
                    int p1=place_in_chain[b],p2=place_in_chain[c];
                    rasp=max(query(chain[b],1,sze[chain[b]],min(p1,p2),max(p1,p2),1),rasp);
                    break;
                }
                else
                {
                    if(niv[root[chain[b]]]<niv[root[chain[c]]]) swap(b,c);
                    rasp=max(query(chain[b],1,sze[chain[b]],place_in_chain[b],place_in_chain[root[chain[b]]],1),rasp);
                    b=tata[root[chain[b]]];
                }
            }
            printf("%d\n",rasp);
        }
    }
}