Cod sursa(job #2294376)

Utilizator andreiudilaUdila Andrei andreiudila Data 2 decembrie 2018 12:37:14
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.36 kb
#include <bits/stdc++.h>
#define pii pair<int,int>
#define fs first
#define sc second
#define pb push_back
#define zeros(x) x&(-x)
#define all(v) v.begin(), v.end()
#define MOD 1000000007
#define oo 2000000010
#define pii pair<int,int>
#define ll long long
#define ld long double
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a))
#define pi 3.14159265359
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

vector <int> v[100010], lant[100010], arb[100010];
int a[100010],d[100010], id[100010], poz[100010], subarb[100010],t[100010];
bool viz[100010];
int i,nrl,m,x,y,n,op;
void dfs(int nod, int depth)
{
    viz[nod] = 1;
    d[nod] = depth;
    subarb[nod] = 1;
    int maxi = 0, f = -1;
    for(int i=0; i<v[nod].size(); ++i)
        if(!viz[v[nod][i]])
        {
             t[v[nod][i]] = nod;
            dfs(v[nod][i], depth+1);
            int nod2 = v[nod][i];

            subarb[nod] += subarb[ nod2 ];

            if(subarb[v[nod][i]] > maxi)
            {
                maxi = subarb[v[nod][i]];
                f = v[nod][i];
            }
        }
    if(f == -1)
    {
        ++nrl;
        lant[nrl].pb(nod);
        poz[nod] = 1;
        id[nod] = nrl;
    }
    else
    {
        lant[id[f]].pb(nod);
        poz[nod] = lant[id[f]].size();
        id[nod] = id[f];
    }

}
void init(int idx,int nod, int l, int r)
{
        if(l == r)
            arb[idx][nod] = a[lant[idx][l-1]];
        else
        {
            init(idx,2*nod,l,(l+r)/2);
            init(idx,2*nod+1,(l+r)/2+1,r);

            arb[idx][nod] = max(arb[idx][2*nod], arb[idx][2*nod+1]);
        }
}

void update(int idx, int nod, int l, int r)
{
    if(l == r) arb[idx][nod] = a[x];
    else
    {
        if(poz[x] > (l+r)/2) update(idx,2*nod+1, (l+r)/2+1, r);
        else update(idx,2*nod,l,(l+r)/2);

        arb[idx][nod] = max(arb[idx][2*nod], arb[idx][2*nod+1]);
    }

}
int query_aint(int idx, int nod, int l, int r, int pozx, int pozy)
{
    if(pozy < l || pozx > r) return 0;
    if(pozx <= l && pozy >= r) return arb[idx][nod];
    else
    {
        int auxr = query_aint(idx,2*nod+1,(l+r)/2+1, r, pozx,pozy);
        int auxl = query_aint(idx,2*nod, l,(l+r)/2, pozx, pozy);

        return max(auxr,auxl);
    }
}
int query(int x, int y)
{
    if(id[x] == id[y])
    {
        return query_aint(id[x],1,1,lant[id[x]].size(),min(poz[x],poz[y]), max(poz[x],poz[y]));
    }
    else
    {
        if( d[lant[id[x]][lant[id[x]].size()-1]] < d[lant[id[y]][lant[id[y]].size()-1]] )
            swap(x,y);

        int aux = query_aint(id[x],1,1,lant[id[x]].size(), poz[x], lant[id[x]].size() );

        return max(aux,query(t[lant[id[x]][lant[id[x]].size()-1]],y));
    }

}
int main()
{
    fin>>n>>m;
    for(i=1; i<=n; ++i)
        fin>>a[i];

    for(i=1; i<n; ++i)
    {
        fin>>x>>y;
        v[x].pb(y);
        v[y].pb(x);
    }

    dfs(1,0);

    for(i=1; i<=nrl; ++i)
    {
        arb[i].resize(4*lant[i].size()+2);
        init(i,1,1,lant[i].size());
    }

    for(i=1;i<=m;++i)
    {
        fin>>op>>x>>y;
        if(op==0)
        {
            a[x] = y;
            update(id[x],1,1,lant[id[x]].size());
        }
        else
        {
            fout<<query(x,y)<<'\n';
        }
    }
        return 0;
}