Cod sursa(job #1324494)

Utilizator smaraldaSmaranda Dinu smaralda Data 22 ianuarie 2015 14:12:01
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.64 kb
#include<stdio.h>
#include<math.h>
#include<vector>
#include<bitset>
using namespace std;

#define ITERATOR vector<int>::iterator
const int NMAX = 1e5 + 5;

vector <int> graph[NMAX];
int n, lim, cnt, nBuckets, val[NMAX], add[NMAX], first[NMAX], last[NMAX], bucket[NMAX], left[NMAX], right[NMAX], ord[NMAX];
bool visDfs[NMAX];
bitset <1000> vis[1000000];

void dfs (int node) {
    ++ cnt;
    ord[cnt] = node;
    first[node] = cnt;

    visDfs[node] = 1;
    for(ITERATOR it = graph[node].begin(); it != graph[node].end(); ++ it)
        if(!visDfs[*it])
            dfs(*it);

    last[node] = cnt;
}

void fill (int block, bool x) {
    int i;

    for(i = left[block]; i <= right[block]; ++ i)
        vis[block][val[i]] = x;
}

void updateVal (int x, int y, int s) {
    int i;

    fill(bucket[x], 0);
    for(i = x; i <= y; ++ i)
        val[i] += s;
    fill(bucket[x], 1);
}

int query (int s) {
    int i, j;

    for(i = 1; i <= nBuckets; ++ i)
        if(s - add[i] >= 0 && vis[i][s - add[i]] == 1)
            for(j = left[i]; j <= right[i]; ++ j)
                if(val[j] + add[i] == s)
                    return ord[j];
    return -1;
}

int main() {
    freopen("arbore.in", "r", stdin);
    freopen("arbore.out", "w", stdout);
    int op, s, m, i, x, y, j, node;

    scanf("%d%d", &n, &m);
    for(i = 1; i < n; ++ i) {
        scanf("%d%d", &x, &y);
        graph[x].push_back(y);
        graph[y].push_back(x);
    }

    dfs(1);

    lim = sqrt(n);

    cnt = 0;
    nBuckets = 1;
    left[1] = 1;
    for(i = 1; i <= n; ++ i) {
        bucket[i] = nBuckets;
        ++ cnt;

        if(cnt == lim) {
            right[nBuckets] = i;

            ++ nBuckets;
            cnt = 0;

            left[nBuckets] = i + 1;
        }
    }
    right[nBuckets] = n;

/*    for(i = 1; i <= n; ++ i)
        fprintf(stderr, "%d ", bucket[i]);
    fprintf(stderr, "\n");
    for(i = 1; i <= nBuckets; ++ i)
        fprintf(stderr, "%d %d\n", left[i], right[i]);*/
    for(i = 1; i <= m; ++ i) {
        scanf("%d", &op);

        if(op == 1) {
            scanf("%d%d", &node, &s);

            x = first[node];
            y = last[node];
            if(bucket[x] == bucket[y])
                updateVal(x, y, s);
            else {
                updateVal(x, right[bucket[x]], s);
                updateVal(left[bucket[y]], y, s);
                for(j = bucket[x] + 1; j <= bucket[y] - 1; ++ j)
                    add[j] += s;
            }
        }
        else {
            scanf("%d", &s);
            printf("%d\n", query(s));
        }
    }
    return 0;
}