Cod sursa(job #1454336)

Utilizator mikeshadowIon Complot mikeshadow Data 26 iunie 2015 09:29:58
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

#define MAXN 100000

typedef vector<int> vi;

int n;
int initial[MAXN];

vi e[MAXN];


int lv[MAXN];
int sz[MAXN];

int numpaths=1;
int path[MAXN];
int pp[MAXN];
int parent[MAXN+5];
int lenpath[MAXN+5];
int lvpath[MAXN+5];

struct node
{
    node *l, *r;
    int x,y;
    int v;

    node(int x, int y): l(0),r(0),x(x),y(y),v(0) {}
};
node *trees[MAXN];

void dfs(int f, int t)
{
    pp[t] = f;
    if (t) lv[t] = lv[f]+1;
    sz[t]=1;
    for (auto i:e[t])
        if (i!=f)
        {
            dfs(t,i);
            sz[t]+=sz[i];
        }

    for (auto i:e[t])
        if (i!=f && 2*sz[i]>=sz[t])
        {
            path[t] = path[i];
            lenpath[path[t]]++;
        } else if (i!=f)
        {
            parent[path[i]] = i;
        }
    if (!path[t]) path[t] = numpaths++,lenpath[path[t]]++;
}

void itrees(node *t)
{
    if (t->x==t->y) return;
    int m = (t->x+t->y)/2;
    t->l = new node(t->x,m);
    t->r = new node(m+1,t->y);
    itrees(t->l);
    itrees(t->r);
}

void dfs2(int f, int t)
{
    if (f+1 && path[f]!=path[t]) lvpath[path[t]] = lvpath[path[f]]+1;
    for (auto i:e[t])
        if (i!=f) dfs2(t,i);
}

void init()
{
    lv[0]=0;
    dfs(-1,0);
    pp[0] = 0;
    lvpath[path[0]]=0;
    parent[path[0]] = 0;
    dfs2(-1,0);

    for (int i=1; i<numpaths; i++)
        trees[i] = new node(0,lenpath[i]-1),itrees(trees[i]);
}

void upd(node *t,int pos,int k)
{
    if (t->x>pos) return;
    if (t->y<pos) return;

    if (t->x == t->y)
        t->v = k;
    else
    {
        upd(t->l,pos,k);
        upd(t->r,pos,k);
        t->v=  max(t->l->v,t->r->v);
    }
}

void update(int x, int k)
{
    node *t;
    t = trees[path[x]];
    int pos = lv[x] - lv[parent[path[x]]];
    upd(t,pos,k);
}

int ans = 0;

void qq(node *t, int l, int r)
{
    if (t->x>r) return;
    if (t->y<l) return;

    if (l<=t->x && r>=t->y)
        ans = max(ans,t->v);
    else
    {
        qq(t->l,l,r);
        qq(t->r,l,r);
    }
}

int query(int x, int y)
{
    ans = 0;

    while (true)
    {
        if (path[x]==path[y])
        {
            int lx = lv[x] - lv[parent[path[x]]];
            int ly = lv[y] - lv[parent[path[y]]];
            qq(trees[path[x]],min(lx,ly),max(lx,ly));
            break;
        } else
        {
            if (lvpath[path[x]]<lvpath[path[y]]) swap(x,y);
            int lx;
            lx = lv[x] - lv[parent[path[x]]];
            qq(trees[path[x]],0,lx);
            x = parent[path[x]];
            x = pp[x];
        }
    }

    return ans;
}

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

int main()
{
    int m;
    fin>>n>>m;

    for (int i=0; i<n; i++)
        fin>>initial[i];

    for (int i=0; i<n-1; i++)
    {
        int x,y;
        fin>>x>>y;
        x--,y--;
        e[x].push_back(y);
        e[y].push_back(x);
    }

    init();

    for (int i=0; i<n; i++)
        update(i,initial[i]);

    for (int i=0; i<m; i++)
    {
        int cod,x,y;
        fin>>cod>>x>>y;
        if (!cod) update(x-1,y);
        else
        {
            int d =query(x-1,y-1);
            fout<<d<<'\n';
        }
    }

    return 0;
}