Cod sursa(job #2938032)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 11 noiembrie 2022 15:44:20
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 2.62 kb
/// Preset de infoarena
#include <fstream>
#include <iostream>
#include <vector>
#include <bitset>

using namespace std;

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

const int maxN = 100005, maxS = 1000005, sizeB = 320;
int n, q, ind, poz1[maxN], poz2[maxN], add[sizeB], nrB, val[maxN], v[maxN];
vector <int> G[maxN];
bitset <maxS> sums[sizeB];

void dfs(int nod, int tata)
{
    poz1[nod] = ++ind;
    v[ind] = nod;
    for(int vecin : G[nod])
        if(vecin != tata)
            dfs(vecin, nod);
    poz2[nod] = ind;
}

void update2(int bucket, int st, int dr, int sum)
{
    int cap_st = max(1, sizeB * bucket), cap_dr = min(n, sizeB * bucket + sizeB - 1);
    for(int i = cap_st; i <= cap_dr; i++)
        sums[bucket][val[i]] = 0;
    for(int i = st; i <= dr; i++)
        val[i] += sum;
    for(int i = cap_st; i <= cap_dr; i++)
        sums[bucket][val[i]] = 1;
}

void update(int st, int dr, int sum)
{
    int b1 = st / sizeB, b2 = dr / sizeB;
    //cout << st << ' ' << dr << ' ' << sum << '\n';
    if(b1 == b2)
    {
        update2(b1, st, dr, sum);
        return;
    }
    update2(b1, st, sizeB * b1 + sizeB - 1, sum);
    update2(b2, sizeB * b2, dr, sum);
    for(int b = b1 + 1; b <= b2 - 1; b++)
        add[b] += sum;
}

int main()
{
    fin >> n >> q;
    nrB = n / sizeB;
    for(int i = 1; i < n; i++)
    {
        int x, y;
        fin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1, 0);
    //for(int i = 1; i <= n; i++)
    //    cout << v[i] << ' ';
    //cout << '\n';
    for(int b = 0; b <= nrB; b++)
        sums[b][0] = 1;
    while(q--)
    {
        int op;
        fin >> op;
        if(op == 1)
        {
            int nod, sum;
            fin >> nod >> sum;
            update(poz1[nod], poz2[nod], sum);
        }
        if(op == 2)
        {
            int sum, ans = 0;
            bool found = 0;
            fin >> sum;
            //cout << sum << '\n';
            for(int b = 0; b <= nrB && !found; b++)
            {
                if(sum < add[b])
                    continue;
                if(sums[b][sum - add[b]] == 0)
                    continue;
                found = 1;
                int cap_st = max(1, sizeB * b), cap_dr = min(n, sizeB * b + sizeB - 1);
                for(int j = cap_st; j <= cap_dr && !ans; j++)
                    if(add[b] + val[j] == sum)
                        ans = v[j];
            }
            if(!found)
                fout << "-1\n";
            if(found)
                fout << ans << '\n';
        }
    }
    return 0;
}