Cod sursa(job #1450609)

Utilizator andreiiiiPopa Andrei andreiiii Data 13 iunie 2015 20:34:31
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.52 kb
#include <algorithm>
#include <bitset>
#include <fstream>
using namespace std;

const int Nmax = 100005, Block = 400, Nblocks = Nmax / Block + 3;
const int Vmax = 1000003;

vector<int> G[Nmax];
int Begin[Nmax], End[Nmax];
int SortedNodes[Nmax];
int cindex;

bitset<Vmax> Exists[Nblocks];
int Sum[Nblocks], Values[Nmax + Block];

int N;

void dfs(const int node, const int father) {
    SortedNodes[++cindex] = node;
    Begin[node] = cindex;
    for (const int p: G[node])
        if (p != father)
            dfs(p, node);
    End[node] = cindex;
}

void updateBlock(int block, int index, int value, bool descending) {
    int begin = block * Block + 1;
    int end = min(N + 1, (block + 1) * Block + 1);

    for (int i = begin; i < end; ++i)
        Exists[block][Values[i]] = false;
    if (!descending)
        for (int i = index; i < end; ++i)
            Values[i] += value;
    else
        for (int i = begin; i <= index; ++i)
            Values[i] += value;
    for (int i = begin; i < end; ++i)
        Exists[block][Values[i]] = true;
}

int main() {
    ifstream fin("arbore.in");
    ofstream fout("arbore.out");

    int M;
    fin >> N >> M;

    for (int i = 1; i < N; ++i) {
        int x, y;
        fin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1, 0);

    while (M-- > 0) {
        int op;
        fin >> op;

        if (op == 1) {
            int node, val;
            fin >> node >> val;

            int left = Begin[node], right = End[node];
            int firstBlock = (left - 1) / Block, lastBlock = (right - 1) / Block;

            for (int i = firstBlock + 1; i < lastBlock; ++i)
                Sum[i] += val;

            if (firstBlock < lastBlock) {
                updateBlock(firstBlock, left, val, false);
                updateBlock(lastBlock, right, val, true);
            } else {
                updateBlock(firstBlock, left, val, false);
                updateBlock(firstBlock, right + 1, -val, false);
            }
        } else {
            int val;
            fin >> val;

            bool found = false;
            for (int i = 0; i * Block < N; ++i) {
                if (val >= Sum[i] && Exists[i][val - Sum[i]]) {
                    found = true;
                    int begin = i * Block + 1, pos;
                    for (pos = begin; Values[pos] != val - Sum[i]; ++pos);
                    fout << SortedNodes[pos] << '\n';
                    break;
                }
            }

            if (!found) fout << "-1\n";
        }
    }

    fin.close();
    fout.close();
}