Cod sursa(job #2924218)

Utilizator DordeDorde Matei Dorde Data 27 septembrie 2022 12:54:39
Problema Arbore Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
int const NMAX = 1e5 + 3 , NRB = 317 , SMAX = 1e6 + 3;
int n , q , x , y , b , nrb;
int eu[NMAX] , upd[NRB] , p[NMAX] , sz[NMAX] , sum[NMAX];
vector<int> v[NMAX];
bitset<SMAX> f[NRB];
void dfs(int x , int t){
    p[x] = eu[n];
    eu[eu[n]++] = x;
    sz[x] = 1;
    for(int& y : v[x])
        if(y != t){
            dfs(y , x);
            sz[x] += sz[y];
        }
}
void updateblocks(int l , int r , int s){
    for(int i = l ; i <= r ; ++ i){
        f[i] = (f[i] >> s);
        upd[i] += s;
    }
}
void brut(int chk , int l , int r , int s){
    for(int i = chk * b ; i < min(n , (chk + 1) * b) ; ++ i)
        f[chk][sum[i]] = 0;
    for(int i = chk * b ; i < min(n , (chk + 1) * b) ; ++ i){
        if(l <= i && i <= r)
            sum[i] += s;
        f[chk][sum[i]] = 1;
    }
}
void update(int x , int s){
    int l = p[x] , r = l + sz[x] - 1;
    if(l / b == r / b){
        brut(l / b , l , r , s);
        return;
    }
    if(l / b + 1 <= r / b - 1)
        updateblocks(l / b + 1 , r / b - 1 , s);
    brut(l / b , l , (l / b + 1) * b - 1 , s);
    brut(r / b , r / b * b , r , s);
}
int query(int s){
    for(int i = 0 ; i < nrb ; ++ i){
        if(!f[i][s])
            continue;
        for(int j = i * b ; j < (i + 1) * b ; ++ j){
            if(sum[j] + upd[i] != s)
                continue;
            return eu[j];
        }
    }
    return -1;
}
int main()
{
    fin >> n >> q;
    for(int i = 1 ; i < n ; ++ i){
        int x , y;
        fin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1 , 0);
    b = 500;
    nrb = n / b + (n % b != 0);
    for(int i = 0 ; i < nrb ; ++ i){
        f[i][0] = 1;
    }
    while(q --){
        int tip , x , s;
        fin >> tip >> x;
        if(tip == 1){
            fin >> s;
            update(x , s);
        }else{
            fout << query(x) << '\n';
        }
    }
    return 0;
}