Cod sursa(job #1022742)

Utilizator ericptsStavarache Petru Eric ericpts Data 5 noiembrie 2013 21:43:10
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <fstream>
#include <vector>
#include <cstdio>
#include <bitset>
#include <algorithm>

using namespace std;

const int MAX_N = 100100;
const int MAX_SQRT = 320;

vector<int> G[MAX_N];
int n,m;
int CR;
int line[MAX_N];
int fst[MAX_N],
    lst[MAX_N];
bool viz[MAX_N];
int actual[MAX_N];


int lim;
int offset[MAX_SQRT];
int start[MAX_SQRT],fin[MAX_SQRT];
int cnt;

bitset<MAX_N * 10> exists[MAX_SQRT];

void DFS(const int node){
    viz[node] = 1;
    line[CR] = node;
    fst[node] = CR;
    ++CR;
    for(vector<int> :: iterator it = G[node].begin() ; it != G[node].end() ; ++it){
        if(viz[*it])
            continue;
        DFS(*it);
    }
    lst[node] = CR - 1;
}

void update(const int node, const int delta){
    const int lo = fst[node], hi = lst[node];
    for(int i = 0 ; i < cnt ; ++i){
        if(fin[i] < lo)
            continue;
        if(start[i] > hi)
            break;
        if(lo <= start[i] && fin[i] <= hi)
            offset[i] += delta;
        else {
            for(int j = start[i] ; j <= fin[i] ; ++j){
                if(j >= lo && j <= hi){
                    exists[i][actual[j]] = 0;
                    actual[j] += delta;
                }
            }
            for(int j = start[i] ; j <= fin[i] ; ++j)
                    exists[i][actual[j]] = 1;
        }
    }
}

int query(const int val){
    for(int i = 0 ; i < cnt ; ++i){
        const int seek = val - offset[i];
        if(seek < 0)
            continue;
        if(exists[i][seek]){
            for(int j = start[i] ; j <= fin[i] ; ++ j)
                if(actual[j] == seek)
                    return line[j];
        }
    }
    return -1;
}

int main()
{
    ifstream in("arbore.in");
    ofstream out("arbore.out");
    in >> n >> m;
    int a,b;
    for(int i = 1 ; i < n ; ++i){
        in >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    DFS(1);

    for(lim = 1 ; lim * lim <= n ; ++lim);
    --lim;

    for(int i = 0; i < CR ; i += lim){
        start[cnt] = i;
        fin[cnt] = i + lim - 1;
        exists[cnt][0] = 1;
        if(CR - 1 < fin[cnt])
            fin[cnt] = CR - 1;
        ++cnt;
    }

    int type;
    while(m--){
        in >> type;
        if(type == 1){
            in >> a >> b;
            update(a, b);
        } else {
            in >> a;
            out << query(a) << "\n";
        }
    }
}