Cod sursa(job #935460)

Utilizator rudarelLup Ionut rudarel Data 3 aprilie 2013 15:05:31
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <cstdio>
#include <bitset>
#include <vector>
#include <math.h>
#include <iostream>
#define maxn 100010
#define maxs 320
 
using namespace std;
 
int n, m, a, b, i, j, sq, tip, p, s, bf;
vector <int> g[maxn];
bitset <10 * maxn> bs[maxs]; //aici tin siru de 1 si 0, daca am sau nu un anumit numar
int add_buc[maxs]; //aici tin cat adun pe fiecare bucata de sqrt
int x[maxn]; //aici tin cat adun pe numerele separate
int pdf[maxn], st[maxn], dr[maxn];
bool viz[maxn];
 
void df(int nod) {
    int i, fiu;
    if (viz[nod])
        return;
    viz[nod] = 1;
    a++;
    pdf[a] = nod;
    st[nod] = a;
 
    for (i = 0; i < g[nod].size(); i++) {
        fiu = g[nod][i];
        df(fiu);
    }
 
    dr[nod] = a;
}
 
inline void update_bitset(int buc, int stg, int drt, int us, int ud, int s) {
    int i;
    //golesc bitsetul
    for (i = stg; i <= drt; i++)
        bs[buc][x[i]] = 0;
    //parcurg numerele, le updatez
    for (i = us; i <= ud; i++)
        x[i] += s;
    //refac bitsetu
    for (i = stg; i <= drt; i++)
        bs[buc][x[i]] = 1;
}
 
inline void get_poz(int poz, int &buc, int &st, int &dr) {
    buc = (poz - 1) / sq + 1;
    st = (buc - 1) * sq + 1;
    dr = buc * sq;
    if (dr > n)
        dr = n;
}
 
inline void update(int nod, int sum) {
    int stg1, drt1, stg2, drt2, buc1, buc2, i;
 
    get_poz(st[nod], buc1, stg1, drt1);
    get_poz(dr[nod], buc2, stg2, drt2);
 
    if (buc2 != buc1) {
        update_bitset(buc1, stg1, drt1, st[nod], drt1, sum);
        update_bitset(buc2, stg2, drt2, stg2, dr[nod], sum);
    }
    else {
        for (i = stg1; i <= drt1; i++)
            bs[buc1][x[i]] = 0;
        for (i = st[nod]; i <= dr[nod]; i++)
            x[i] += sum;
        for (i = stg1; i <= drt1; i++)
            bs[buc1][x[i]] = 1;
    }
     
 
    for (i = buc1 + 1; i < buc2; i++)
        add_buc[i] += sum;
}
 
int query(int sum) {
    int buc, found = 0, i, st, dr;
    for (i = 1; i <= bf; i++)
        if (sum - add_buc[i] >= 0)
            if (bs[i][sum - add_buc[i]] == 1) {
                found = i;
                break;
            }
 
    if (found == 0)
        return -1;
 
    buc = found;
    st = (found - 1) * sq + 1;
    dr = found * sq;
 
    found = 0;
    for (i = st; i <= dr; i++)
        if (x[i] == sum - add_buc[buc]) {
            found = i;
            break;
        }
 
    return pdf[found];
}
 
int main() {
    freopen("arbore.in", "r", stdin);
    freopen("arbore.out", "w", stdout);
 
    scanf("%d%d", &n, &m);
    sq = (int) sqrt(n);
    get_poz(n, bf, a, b);
    for (i = 1; i <= bf; i++)
        bs[i][0] = 1;
 
    for (i = 1; i < n; i++) {
        scanf("%d%d", &a, &b);
        g[a].push_back(b);
        g[b].push_back(a);
    }
 
    a = 0;
    df(1);
 
    for (i = 1; i <= m; i++) {
        scanf("%d", &tip);
        if (tip == 1) {
            scanf("%d%d", &p, &s);
            update(p, s);
        }
        else {
            scanf("%d", &s);
            printf("%d\n", query(s));
        }
    }
 
    return 0;
}