Cod sursa(job #2506064)

Utilizator IoanaDraganescuIoana Draganescu IoanaDraganescu Data 7 decembrie 2019 13:50:42
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <cmath>

using namespace std;

ifstream fin("arbore.in");
ofstream fout("arbore.out");

const int Nmax = 100000, SqrtN = 320, Valmax = 1000000;

vector <int> g[Nmax + 5];
bitset <Valmax + 5> b[SqrtN + 5];
int n, m, k, first[Nmax + 5], last[Nmax + 5], nr, sq, e[Nmax + 5], el[Nmax + 5], start[SqrtN + 5], stop[SqrtN + 5], val[SqrtN + 5];
bool use[Nmax + 5];

void Read(){
    fin >> n >> m;
    for (int i = 1; i < n; i++){
        int x, y;
        fin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
}

void DFS(int node){
    use[node] = 1;
    first[node] = ++k;
    el[k] = node;
    for (auto i : g[node])
        if (!use[i])
            DFS(i);
    last[node] = k;
}

void Constr(){
    sq = sqrt(n);
    for (int i = 1; i <= n; i++){
        if (i % sq == 1){
            stop[nr] = i - 1;
            nr++;
            start[nr] = i;
        }
        b[nr][0] = 1;
    }
    if (!stop[nr])
        stop[nr] = n;
}

void Update(int f, int l, int value){
    for (int i = 1; i <= nr; i++){
        if (f <= start[i] && stop[i] <= l)
            val[i] += value;
        else if (f > start[i] && stop[i] > l)
            for (int j = f; j <= l; j++){
                e[j] += value;
                b[i][e[j]] = 1;
            }
        else if (f > start[i] && f <= stop[i])
            for (int j = f; j <= stop[i]; j++){
                e[j] += value;
                b[i][e[j]] = 1;
            }
        else if (stop[i] > l && l >= start[i]){
            for (int j = start[i]; j <= l; j++){
                e[j] += value;
                b[i][e[j]] = 1;
            }
        }
    }
}

int Query(int s){
    for (int i = 1; i <= nr; i++){
        if (s - val[i] < 0)
            continue;
        if (b[i][s - val[i]])
            for (int j = start[i]; j <= stop[i]; j++)
                if (e[j] == s - val[i])
                    return el[j];
    }
    return -1;
}

int main(){
    Read();
    DFS(1);
    Constr();
    while (m--){
        int op;
        fin >> op;
        if (op == 1){
            int p, s;
            fin >> p >> s;
            Update(first[p], last[p], s);
        }
        else{
            int s;
            fin >> s;
            fout << Query(s) << '\n';
        }
    }
    return 0;
}