Cod sursa(job #2397227)

Utilizator lupulescu2001Lupulescu Vlad lupulescu2001 Data 4 aprilie 2019 11:39:38
Problema Arbore Scor 10
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 2.76 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <cmath>

using namespace std;

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

const int nMax = 100000;
int n, m, radacina, bf[nMax + 5], bl[nMax + 5];
vector <int> g[nMax + 5];
int first[nMax + 5], last[nMax + 5];
int dim;
bitset<nMax + 5> fnd[350];
int bucket, sumbuck[350];
int sum[nMax + 5];
int liniar[nMax + 5];

void DFS(int nod, int tt) {
    dim++;
    liniar[dim] = nod;
    first[nod] = dim;
    for (auto i : g[nod])
        if (i != tt)
            DFS(i, nod);
    last[nod] = dim;
}

void Update(int nod, int val) {
    int f = first[nod], l =last[nod];
    for (int i = 1; i <= bucket; i++) {
        if (l < bf[i])
            continue;
        if (l < bf[i])
            return;
        if (f <= bf[i] && l >= bl[i])
            sumbuck[i] += val;
        if (f > bf[i] && l >= bl[i]) {
            fnd[i] ^= fnd[i];
            for (int j = bf[i]; j <= bl[i]; j++) {
                if (j >= f)
                    sum[j] += val;
                sum[j] += sumbuck[i];
                fnd[i][sum[j]] = 1;
            }
            sumbuck[i] = 0;
        }
        if (f <= bf[i] && l < bl[i]) {
            fnd[i] ^= fnd[i];
            for (int j = bf[i]; j <= bl[i]; j++) {
                if (j <= l)
                    sum[j] += val;
                sum[j] += sumbuck[i];
                fnd[i][sum[j]] = 1;
            }
            sumbuck[i] = 0;
        }
        if (f > bf[i] && l < bl[i]) {
            fnd[i] ^= fnd[i];
            for (int j = bf[i]; j <= bl[i]; j++) {
                if (j <= l && j >= f)
                    sum[j] += val;
                sum[j] += sumbuck[i];
                fnd[i][sum[j]] = 1;
            }
            sumbuck[i] = 0;
        }
    }
}

int Query(int val) {
    for (int i = 1; i <= bucket; i++) {
        if (sumbuck[i] > val)
            continue;
        int x = val - sumbuck[i];
        if (fnd[i][x] == 1)
            for (int j = bf[i]; j <= bl[i]; j++)
                if (sum[j] == x)
                    return liniar[j];
    }
    return - 1;
}

int main() {
    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);
    }
    int k = sqrt(n);
    DFS(1, 0);
    for (int i = 1; i <= n; i += k) {
        bucket++;
        bf[bucket] = i;
        bl[bucket] = min(n, bucket * k);
        fnd[bucket][0] = 1;
    }
    for (int i = 1; i <= m; i++) {
        int x, nod, s;
        fin >> x;
        if (x == 1) {
            fin >> nod >> s;
            Update(nod, s);
        } else {
            fin >> s;
            fout << Query(s) << '\n';
        }
    }
}