Cod sursa(job #1397199)

Utilizator danalex97Dan H Alexandru danalex97 Data 23 martie 2015 12:37:16
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.41 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

ifstream F("heavypath.in");
ofstream G("heavypath.out");

const int N = 100010;

struct aint {
    vector<int> a;
    int n;

    void init(int n)
    {
        this->n = n;
        a.resize(n*4+5);
    }

    void _update(int n,int l,int r,int p,int v)
    {
        if ( l == r )
        {
            a[n] = v;
            return;
        }

        int m = (l + r) / 2;
        if ( p <= m )
            _update(n*2,l,m,p,v);
        else
            _update(n*2+1,m+1,r,p,v);
        a[n] = max(a[n*2],a[n*2+1]);
    }

    int _query(int n,int l,int r,int il,int ir)
    {
        if ( l > ir || r < il ) return 0;
        if ( il <= l && r <= ir ) return a[n];

        int m = (l + r) / 2;
        return max(_query(n*2,l,m,il,ir),_query(n*2+1,m+1,r,il,ir));
    }

    void update(int p,int v)
    {
        _update(1,1,n,p,v);
    }

    int query(int l,int r)
    {
        if ( l > r )
            swap(l,r);
        if ( l == 0 )
            return 0;
        return _query(1,1,n,l,r);
    }
};

vector<int> v[N];
int n,m,vl[N];
aint arb[N];

int mk[N],sz[N];
int p[N],ln[N],chain[N],nbr,height[N],dad[N];

void compute_chains(int x)
{
    int ok = 0;
    mk[x] = 1;
    sz[x] = 1;

    int mx = 0, yy = 0;
    for (int i=0;i<int(v[x].size());++i)
    {
        int y = v[x][i];
        if ( !mk[y] )
        {
            compute_chains(y);
            sz[x] += sz[y];
            if ( sz[y] > mx )
            {
                mx = sz[y];
                yy = y;
            }
            ok = 0;
        }
    }

    if ( !ok )
    {
        chain[x] = ++nbr;
        return;
    }
    else
        chain[x] = chain[yy];
}

int lvl[N];

void compute_parents(int x,int dd)
{
    mk[x] = 1;
    p[x] = ++ln[chain[x]];
    dad[x] = dd;
    for (int i=0;i<int(v[x].size());++i)
    {
        int y = v[x][i];
        if ( !mk[y] )
        {
            if ( chain[y] != chain[x] )
            {
                compute_parents(y,x);
                lvl[ chain[y] ] = lvl[ chain[x] ] + 1;
            }
            else
            {
                compute_parents(y,dd);
            }
        }
    }
}

int main()
{
    F>>n>>m;
    for (int i=1;i<=n;++i)
        F>>vl[i];
    for (int i=1,x,y;i<n;++i)
    {
        F>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }

    compute_chains(1);
    memset(mk,0,sizeof(mk));
    compute_parents(1,0);

    for (int i=1;i<=n;++i) arb[chain[i]].init(ln[chain[i]]);
    for (int i=1;i<=n;++i) arb[chain[i]].update( p[i],vl[i] );

    for (int i=1,t,x,y;i<=m;++i)
    {
        F>>t>>x>>y;
        if ( t == 0 )
        {
            arb[ chain[x] ].update( p[x],y );
        }
        else
        {
            int ans = 0;
            while ( chain[x] != chain[y] )
            {
                if ( lvl[ chain[x] ] > lvl[ chain[y] ] )
                {
                    ans = max(ans,arb[chain[x]].query(1,p[x]));
                    x = dad[x];
                }
                else
                {
                    ans = max(ans,arb[chain[y]].query(1,p[y]));
                    y = dad[y];
                }
            }
            ans = max(ans,arb[chain[x]].query(p[x],p[y]));
            G<<ans<<'\n';
        }
    }
}