Cod sursa(job #1521561)

Utilizator cojocarugabiReality cojocarugabi Data 10 noiembrie 2015 17:37:39
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.87 kb
# include <bits/stdc++.h>
using namespace std;
ifstream fi("heavypath.in");
ofstream fo("heavypath.out");
const int N = 1000005;
int *s[N];
vector < int > v[N];
int dp[17][N];
int h[N];
int to[N];
int ind[N];
int sum[N];
int val[N];
int p[N];
int mar[N];
void dfs(int prec,int node)
{
    dp[0][node] = prec;
    h[node] = h[prec] + 1;
    sum[node] = 1;
    for (auto it : v[node])
        if (it != prec)
            dfs(node,it),sum[node] += sum[it];
}
int sh(int x,int y)
{
    for (int i = 16;i+1;--i)
        if (y>>i&1) x = dp[i][x];
    return x;
}
int lca(int x,int y)
{
    if (h[x] > h[y])
        x = sh(x,h[x] - h[y]);
    else y = sh(y,h[y] - h[x]);
    for (int i = 16;i+1 && x != y;--i)
        if (dp[i][x] != dp[i][y])
            x = dp[i][x],y = dp[i][y];
    if (x == y) return x;
    return dp[0][x];
}
void upd(int id,int p,int u,int pos,int val,int node)
{
    if (p == u) s[id][node] = val;
    else
    {
        int m = (p+u)/2;
        if (pos <= m) upd(id,p,m,pos,val,node<<1);
        else upd(id,m+1,u,pos,val,node<<1|1);
        s[id][node] = max(s[id][node<<1],s[id][node<<1|1]);
    }
}
int qry(int id,int p,int u,int l,int r,int node)
{
    if (l <= p && u <= r) return s[id][node];
    int mx = 0;
    int m = (p+u)/2;
    if (l <= m) mx = max(mx,qry(id,p,m,l,r,node<<1));
    if (m+1<=r) mx = max(mx,qry(id,m+1,u,l,r,node<<1|1));
    return mx;
}
int qu(int x,int y)
{
    if (to[x] == to[y])
        return qry(to[x],1,mar[to[x]],ind[x],ind[y],1);
    else
        return max(qry(to[y],1,mar[to[y]],1,ind[y],1),qu(x,p[y]));
}
int query(int x,int y)
{
    int lc = lca(x,y);
    return max(qu(lc,x),qu(lc,y));
}
void update(int x,int y)
{
    upd(to[x],1,mar[to[x]],ind[x],y,1);
}
int arb = 0;
void DFS(int prec,int node,int len,int pl)
{
    p[node] = pl;
    if (sum[node] == 1)
    {
        s[++arb] = new int[2*len+5];
        mar[arb] = len;
        ind[node] = len;
        to[node] = arb;
    }
    else
    {
        int mx = 0,where = 0;
        for (auto it : v[node])
            if (it != prec)
                mx = max(mx,sum[it]);
        for (auto it : v[node])
            if (it != prec)
                where = it;
        DFS(node,where,len+1,pl);
        to[node] = to[where];
        ind[node] = len;
        for (auto it : v[node])
            if (it != prec && it != where)
                DFS(node,it,1,node);
    }
}
int main(void)
{
    int n,m;
    fi>>n>>m;
    for (int i = 1;i <= n;++i) fi>>val[i];
    for (int i = 1;i < n;++i)
    {
        int a,b;
        fi>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    dfs(0,1);
    for (int i = 1;i < 17;++i)
        for (int j = 1;j <= n;++j)
            dp[i][j] = dp[i-1][dp[i-1][j]];
    DFS(0,1,1,0);
    for (int i = 1;i <= n;++i) update(i,val[i]);
    while (m --)
    {
        int a,b,c;
        fi>>a>>b>>c;
        if (!a) update(b,c);
        else fo << query(b,c) << '\n';
    }
    return 0;
}