Cod sursa(job #1133343)

Utilizator deneoAdrian Craciun deneo Data 4 martie 2014 19:32:43
Problema Arbore Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.64 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <bitset>
#include <vector>

using namespace std;

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

#define low(x) (lim * (x - 1) + 1)
#define high(x) (lim * x)

const int MAXN = 100100;
const int MAXS = 1000100;
const int MAXLIM = 350;

int n, q, p, lim, bucket_sum[MAXLIM], elem[MAXN], start[MAXN], last[MAXN], pos_to_nod[MAXN];
bitset<MAXS> in_bucket[MAXLIM];
vector<int> graf[MAXN];

void dfs (int nod, int dad) {
    start[nod] = ++p;
    pos_to_nod[p] = nod;

    for (int i = 0; i < (int)graf[nod].size(); ++i) {
        int node = graf[nod][i];
        if (node != dad)
            dfs (node, nod);
    }

    last[nod] = p;
}

int get_bucket (int x) {
    if (x % lim == 0)
        return x / lim;
    return x / lim + 1;
}

void update_bucket (int bucket, int start, int last, int s) {
    int st = max (start, low(bucket));
    int dr = min (last, high(bucket));
    for (int i = low(bucket); i <= high(bucket); ++i)
        in_bucket[bucket][elem[i]] = 0;
    for (int i = st; i <= dr; ++i)
        elem[i] += s;
    for (int i = low(bucket); i <= high(bucket); ++i)
        in_bucket[bucket][elem[i]] = 1;
}

void update (int start, int last, int s) {
    for (int bucket = get_bucket(start); bucket <= get_bucket(last); ++bucket) {
        if (start <= low(bucket) && high(bucket) <= last)
            bucket_sum[bucket] += s;
        else if (start > low(bucket) && start <= high(bucket))
            update_bucket (bucket, start, last, s);
        else if (last >= low(bucket) && last < high(bucket))
            update_bucket (bucket, start, last, s);
    }
}

int query (int s, int lastBucket) {
    for (int bucket = 1; bucket <= lastBucket; ++bucket)
        if (bucket_sum[bucket] <= s && in_bucket[bucket][s - bucket_sum[bucket]])
            for (int i = low(bucket); i <= high(bucket); ++i)
                if (elem[i] == s - bucket_sum[bucket])
                    return pos_to_nod[i];
    return -1;
}

int main() {
    fin >> n >> q;
    lim = sqrt(n);

    for (int i = 1; i < n; ++i) {
        int a, b; fin >> a >> b;
        graf[a].push_back(b);
        graf[b].push_back(a);
    }

    dfs (1, 0);

    for (int i = 1; i <= get_bucket(n); ++i)
        in_bucket[i][0] = 1;

    for (int i = 1; i <= q; ++i) {
        int type; fin >> type;

        if (type == 1) {
            int nod, s; fin >> nod >> s;
            update (start[nod], last[nod], s);
        }
        else {
            int s; fin >> s;
            fout << query(s, get_bucket(n)) << "\n";
        }
    }

    return 0;
}