Cod sursa(job #1340464)

Utilizator dariusdariusMarian Darius dariusdarius Data 11 februarie 2015 20:35:14
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.74 kb
#include <cmath>

#include <algorithm>
#include <bitset>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
const int MAX_N = 100005;
const int MAX_K = 400;
struct Piece {
    int added;
    bitset<1000005> values;
} p[MAX_K];

vector<int> tree[MAX_N];
int n, k, depth[MAX_N];
int start[MAX_N];
int finish[MAX_N];
int sum[MAX_N];

void dfs(int node, int father = 0) {
    depth[++ k] = node;
    start[node] = k;
    for (vector<int> :: iterator it = tree[node].begin(); it != tree[node].end(); ++ it) {
        if (*it != father) {
            dfs(*it, node);
        }
    }
    finish[node] = k;
}

void manual_update(int index, int x, int y, int value) {
    int first = (index - 1) * k + 1;
    int last = min(index * k, n);
    for (int i = first; i <= last; ++ i) {
        p[index].values[sum[i]] = 0;
    }
    for (int i = first; i <= last; ++ i) {
        sum[i] += p[index].added;
        if (x <= i && i <= y) {
            sum[i] += value;
        }
        p[index].values[sum[i]] = 1;
    }
    p[index].added = 0;
}

void update(int x, int y, int value) {
    int px = (x + k - 1) / k, py = (y + k - 1) / k;
    if (px == py) {
        manual_update(px, x, y, value);
        return;
    }
    manual_update(px, x, min(px * k, n), value);
    manual_update(py, (py - 1) * k + 1, y, value);
    for (int i = px + 1; i < py; ++ i) {
        p[i].added += value;
    }
}

int main() {
    ifstream fin("arbore.in");
    ofstream fout("arbore.out");
    int m, x, y;
    fin >> n >> m;
    for (int i = 1; i < n; ++ i) {
        fin >> x >> y;
        tree[x].push_back(y);
        tree[y].push_back(x);
    }
    dfs(1);
    k = static_cast<int>(sqrt(1.0 * n));
    int pieces = (n + k - 1) / k;
    for (int i = 1; i <= pieces; ++ i) {
        p[i].values[0] = true;
    }
    for (int i = 1; i <= m; ++ i) {
        int type;
        fin >> type;
        if (type == 1) {
            int node, value;
            fin >> node >> value;
            update(start[node], finish[node], value);
        } else {
            int value; int ok = -1;
            fin >> value;
            for (int i = 1; i <= pieces; ++ i) {
                if (value >= p[i].added && p[i].values[value - p[i].added]) {
                    int first = (i - 1) * k + 1;
                    int last = min(i * k, n);
                    for (int j = first; j <= last; ++ j) {
                        if (sum[j] + p[i].added == value) {
                            ok = depth[j];
                            break;
                        }
                    }
                    break;
                }
            }

            fout << ok << "\n";
        }
    }
    return 0;
}