Cod sursa(job #931576)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 28 martie 2013 12:48:12
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <iostream>
#include <cstdio>
#include <bitset>
#include <vector>

#define SQRT_MAX 330
#define MAX 100005
#define BMAX 1000005

using namespace std;

int N, M, K, NR, poz;
int First[MAX], Last[MAX], V[MAX], Start[SQRT_MAX], Stop[SQRT_MAX], ap[MAX], sum[SQRT_MAX], val[MAX];
char buff[BMAX];
vector<int> G[MAX];
bitset<BMAX> P[SQRT_MAX];

inline int getInt() {
    int X = 0;
    while(buff[poz] < '0' || buff[poz] > '9')
        if(++poz == BMAX) fread(buff, 1, BMAX, stdin), poz = 0;
    while(buff[poz] >= '0' && buff[poz] <= '9') {
        X = X * 10 + buff[poz++] - '0';
        if(poz == BMAX) fread(buff, 1, BMAX, stdin), poz = 0;
    } return X;
}

void citire() {
    freopen("arbore.in", "r", stdin); freopen("arbore.out", "w", stdout);
    fread(buff, 1, BMAX, stdin);
    N = getInt(), M = getInt();
    for(int i = 1, A, B; i < N; i++) {
        A = getInt(); B = getInt();
        G[A].push_back(B);
        G[B].push_back(A);
    }
}

void dfs(const int &nod, const int &dad) {
    V[++K] = nod;
    First[nod] = K;
    for(size_t i = 0; i < G[nod].size(); i++) {
        int dest = G[nod][i];
        if(dest == dad) continue;
        dfs(dest, nod);
    } Last[nod] = K;
}

void createLists() {
    int S;
    for(S = 1; S * S <= N; S++);
    S--;
    for(int i = 1, region = 0; i <= N; i++) {
        if(i % S == 1) {
            Stop[region++] = i - 1;
            P[region][0] = 1;
            Start[region] = i;
            NR = region;
        }
        ap[i] = region;
    } Stop[NR] = N;
}

inline void Update(const int &L, const int &R, const int &S) {
    for(int i = ap[L]; i <= ap[R]; i++) {
        if(L <= Start[i] && Stop[i] <= R) {
            sum[i] += S;
            continue;
        }
        for(int j = Start[i]; j <= Stop[i]; j++) {
            P[i][val[j]] = 0;
            val[j] = sum[i] + (L <= j && j <= R ? S : 0);
        } sum[i] = 0;
        for(int j = Start[i]; j <= Stop[i]; j++)
            P[i][val[j]] = true;
    }
}

inline int Query(const int &S) {
    for(int i = 1; i <= NR; i++) {
        if(sum[i] > S) continue;
        if(P[i][S - sum[i]]) {
            for(int j = Start[i]; j <= Stop[i]; j++)
                if(val[j] == S - sum[i])
                    return V[j];
        }
    } return -1;
}

void solve() {
    dfs(1, 0);
    createLists();
    for(int i = 1, T, P, S; i <= M; i++) {
        T = getInt();
        switch(T) {
            case 1: P = getInt(), S = getInt(); Update(First[P], Last[P], S); break;
            case 2: S = getInt(); printf("%d\n", Query(S)); break;
        }
    } fclose(stdin); fclose(stdout);
}


int main() {
    citire();
    solve();
    return 0;
}