Cod sursa(job #2937710)

Utilizator cristia_razvanCristia Razvan cristia_razvan Data 10 noiembrie 2022 21:03:15
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mp make_pair
#define dbg(x) cout << #x << ": " << x << "\n";
#define sz(x) ((int)x.size())

const string fn = "arbore";
ifstream fin(fn + ".in");
ofstream fout(fn + ".out");

const int mxn = 100000;

int n, m, p;
int sq, b;

vector<int> g[mxn + 5];
int st[mxn + 5], dr[mxn + 5], nodd[mxn + 5];
bitset<mxn + 5> viz;
bitset<mxn + 5> f[325];

int a[mxn + 5], all[mxn + 5];

inline int block(int i)
{
    return i / sq + ((i % sq) > 0);
}

void dfs(int nod)
{
    viz[nod] = 1;
    st[nod] = ++p;
    nodd[p] = nod;
    for (auto i : g[nod])
    {
        if (!viz[i])
            dfs(i);
    }
    dr[nod] = p;
}

void upd(int nod, int val)
{

    int b1 = block(st[nod]), b2 = block(dr[nod]);
    for (int i = st[nod]; block(i) == b1 && i <= dr[nod]; ++i)
    {
        f[b1][a[i]] = 0;
        a[i] += val;
    }

    for (int i = (b1 - 1) * sq + 1; i <= min(b1 * sq, n); ++i)
        f[b1][a[i]] = 1;
    if (b1 != b2)
    {
        for (b1 = b1 + 1; b1 < b2; b1++)
            all[b1] += val;
        for (int i = (b2 - 1) * sq + 1; i <= dr[nod]; ++i)
        {
            f[b2][a[i]] = 0;
            a[i] += val;
        }

        for (int i = (b2 - 1) * sq + 1; i <= min(b2 * sq, n); ++i)
            f[b2][a[i]] = 1;
    }
}

int qry(int s)
{
    for (int i = 1; i <= b; ++i)
        if (s - all[i] >= 0 && f[i][s - all[i]])
        {
            for (int j = (i - 1) * sq + 1; j <= min(i * sq, n); ++j)
                if (a[j] == s - all[i])
                    return nodd[j];
        }
    return -1;
}

int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie();

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

    dfs(1);
    sq = sqrt(n);
    b = block(n);

    for (int i = 0; i < b; ++i)
        f[i][0] = 1;

    while (m--)
    {
        int op, x, y;
        fin >> op;
        if (op == 1)
        {
            fin >> x >> y;
            upd(x, y);
        }
        else
        {
            fin >> x;
            fout << qry(x) << '\n';
        }
    }

    return 0;
}