Cod sursa(job #2401351)

Utilizator popabogdanPopa Bogdan Ioan popabogdan Data 9 aprilie 2019 17:12:14
Problema Arbore Scor 85
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <bits/stdc++.h>

#define Nmax 100005
#define Vmax 1000001
#define sqrtMax 318

using namespace std;

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

struct batog
{
    int le, ri;
    int V;
    bitset <Vmax> exists;
};

batog B[sqrtMax];

int N, M, L, numOfBlocks;
int SIZE;
vector <int> G[Nmax];
int add[Nmax];
int le[Nmax], ri[Nmax];
bool vis[Nmax];
int nodes[Nmax];
int pos[Nmax];
int i, t, P, S;
int block;

void DFS(int node)
{
    vis[node] = true;
    le[node] = ++L;
    nodes[L] = node;
    for(auto it : G[node])
        if(!vis[it])
            DFS(it);
    ri[node] = L;
}

void upE(int block, int t)
{
    for(i = B[block].le; i <= B[block].ri; i++)
        B[block].exists[add[i]] = t, pos[i] = block;
}

void addInt(int le, int ri, int val)
{
    for(i = le; i <= ri; i++)
        add[i] += val;
}

void update(int le, int ri, int val)
{
    for(block = pos[le] + 1; block < pos[ri]; block++)
        B[block].V += val;
    if(pos[le] == pos[ri])
    {
        upE(pos[le], 0);
        addInt(le, ri, val);
        upE(pos[le], 1);
    }
    else
    {
        upE(pos[le], 0);
        addInt(le, B[pos[le]].ri, val);
        upE(pos[le], 1);
        upE(pos[ri], 0);
        addInt(B[pos[ri]].le, ri, val);
        upE(pos[ri], 1);
    }
}

int query(int S)
{
    for(block = 1; block <= numOfBlocks; block++)
        if(S >= B[block].V && B[block].exists[S - B[block].V] == 1)
            for(i = B[block].le; i <= B[block].ri; i++)
                if(add[i] + B[block].V == S)
                    return nodes[i];
    return -1;
}

int main()
{
    fin >> N >> M;
    SIZE = sqrt(N);
    do
    {
        ++numOfBlocks;
        B[numOfBlocks].le = B[numOfBlocks - 1].ri + 1;
        B[numOfBlocks].ri = B[numOfBlocks - 1].ri + SIZE;
        B[numOfBlocks].ri = min(B[numOfBlocks].ri, N);
        upE(numOfBlocks, 1);
    }while(B[numOfBlocks].ri != N);
    for(i = 1; i < N; i++)
    {
        int x, y;
        fin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    DFS(1);
    while(M--)
    {

        fin >> t;
        if(t == 1)
        {
            fin >> P >> S;
            update(le[P], ri[P], S);
        }
        else
        {
            fin >> S;
            fout << query(S) << "\n";
        }
    }
    return 0;
}