Cod sursa(job #1893687)

Utilizator marcdariaDaria Marc marcdaria Data 25 februarie 2017 21:41:46
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <fstream>
#include <bitset>
#include <vector>

using namespace std;

#define BSIZE 512
#define MAXN 100005
int Block[MAXN], Start[MAXN], End[MAXN], Node[MAXN], Val[MAXN], B[MAXN], E[MAXN], Sum[MAXN], Sort[MAXN];
bool Updated[MAXN];
bitset<1000005> Have[256];

vector<int> G[MAXN];

int timer = 0, blocks;

void dfs(int node) {
    B[node] = ++timer;
    Node[timer] = node;
    for(auto vec : G[node])
        if(!B[vec])
            dfs(vec);
    E[node] = timer;
}

void Update(int l, int r, int delta) {
    while(l <= r) {
        int b = Block[l];

        if(l == Start[b] && End[b] <= r) {
            Sum[b] += delta;
            l = End[b] + 1;
        } else {
            Have[b][Val[l]] = 0;
            Val[l] += delta;
            Updated[b] = 0;
            l += 1;
        }
    }
}

void Init(int n) {
    for(int i=1; i<=n; i++) {
        Block[i] = i / BSIZE;
        End[Block[i]] = i;
        if(Start[Block[i]] == 0)
            Start[Block[i]] = i;
        Sort[i] = i;
    }
    blocks = Block[n] + 1;
}

void Refresh(int b) {
    for(int i = Start[b]; i <= End[b]; ++i)
        Have[b][Val[i]] = 1;
    Updated[b] = 1;
}

void Op1(int n, int s) {
    Update(B[n], E[n], s);
}
int Op2(int s) {
    for(int b = 0; b < blocks; b ++) {
        if(s - Sum[b] < 0)
            continue;

        if(!Updated[b])
            Refresh(b);

        if(Have[b][s - Sum[b]]) {
            for(int i = Start[b]; i <= End[b]; ++i)
                if(Val[i] == s - Sum[b])
                    return Node[i];
        }
    }

    return -1;
}

void Read(int &a) {
    char c;
    for(c = getchar(); !isdigit(c); c = getchar());
    for(a = 0; isdigit(c); c = getchar())
        a = (a << 1) + (a << 3) + c - '0';
}

int main() {
    ifstream cin("arbore.in");
    ofstream cout("arbore.out");

    int n, m, a, b, t, s;
    Read(n); Read(m);

    for(int i=1; i<n; i++) {
        Read(a); Read(b);
        G[a].push_back(b);
        G[b].push_back(a);
    }

    Init(n);
    dfs(1);

    while(m--) {
        Read(t);
        if(t == 2) {
            Read(s);
            cout << Op2(s) << '\n';
        } else {
            Read(a); Read(s);
            Op1(a, s);
        }
    }

    return 0;
}