Cod sursa(job #2334299)

Utilizator FrequeAlex Iordachescu Freque Data 2 februarie 2019 14:49:34
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.03 kb
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define enter cout << '\n'

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <pii> vii;
typedef vector <ll> vl;
typedef vector <pll> vll;
typedef queue <int> qi;
typedef queue <pii> qii;
typedef queue <ll> ql;
typedef queue <pll> qll;

const double EPSILON = 0.0000000001;
const int INF = 0x3f3f3f3f;
const int MOD = 100003;
const int NMAX = 1e5 + 5;
const int EMAX = 20;

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

vector <int> graph[NMAX];
pii rmq[EMAX][2 * NMAX];
int n, m;
int rmq_size, aib_size;
int cost[NMAX], lg[2 * NMAX];
int ap[2 * NMAX], st[2 * NMAX], dr[2 * NMAX], aib[2 * NMAX];
bool vis[NMAX];

int zeros(int x)
{
    return x ^ (x & (x - 1));
}

void update_aib(int poz, int val)
{
    for (int i = poz; i <= 2 * n; i += zeros(i))
        aib[i] += val;
}

int query_aib(int poz)
{
    int rez = 0;
    for (int i = poz; i; i -= zeros(i))
        rez += aib[i];
    return rez;
}

int sum(int st, int dr)
{
    return query_aib(dr) - query_aib(st - 1);
}

void dfs(int node, int depth)
{
    vis[node] = true;

    rmq[0][++rmq_size] = mp(depth, node);
    ap[node] = rmq_size;

    update_aib(++aib_size, cost[node]);
    st[node] = aib_size;

    for (int next: graph[node])
        if (!vis[next])
        {
            dfs(next, depth + 1);
            rmq[0][++rmq_size] = mp(depth, node);
        }

    update_aib(++aib_size, -cost[node]);
    dr[node] = aib_size;
}

void init_log()
{
    for (int i = 2; i < 2 * NMAX; ++i)
        lg[i] = lg[i / 2] + 1;
}

void init_rmq()
{
    for (int i = 1; (1 << i) <= rmq_size; ++i)
        for (int j = 1; j + (1 << i) - 1 <= rmq_size; ++j)
            rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
}

int query_rmq(int l, int r)
{
    l = ap[l];
    r = ap[r];
    if (l > r) swap(l, r);

    int len = r - l + 1;
    pii minimum = min(rmq[lg[len]][l], rmq[lg[len]][r - (1 << lg[len]) + 1]);
    return minimum.se;
}

void read()
{
    int x, y;

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

int main()
{
    read();
    dfs(1, 0);
    init_log();
    init_rmq();

    while (m--)
    {
        int cod, x, y;
        fin >> cod >> x >> y;

        if (cod == 1)
        {
            update_aib(x, -sum(x, x) + y);
        }
        else
        {
            int lca = query_rmq(x, y);
            x = st[x];
            y = st[y];
            fout << sum(st[lca], x) + sum(st[lca], y) - sum(st[lca], st[lca]) << '\n';
        }
    }

    return 0;
}

/*
10
3 1 2 6 4 3 8 4 1 2
1 2
2 4
2 5
2 6
5 9
1 3
3 7
7 10
3 8


*/