Cod sursa(job #2401374)

Utilizator popabogdanPopa Bogdan Ioan popabogdan Data 9 aprilie 2019 17:29:16
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 2.32 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");

int le[sqrtMax], ri[sqrtMax];
int V[sqrtMax];
bitset <Vmax> exists[sqrtMax];
int N, M, L, numOfBlocks;
int SIZE;
vector <int> G[Nmax];
int add[Nmax];
bool vis[Nmax];
int nodes[Nmax];
int pos[Nmax];
int Left[Nmax], Right[Nmax];

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

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

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

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

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

int main()
{
    fin >> N >> M;
    SIZE = sqrt(N);
    do
    {
        ++numOfBlocks;
        le[numOfBlocks] = ri[numOfBlocks - 1] + 1;
        ri[numOfBlocks] = ri[numOfBlocks - 1] + SIZE;
        ri[numOfBlocks] = min(ri[numOfBlocks], N);
        upE(numOfBlocks, 1);
    }while(ri[numOfBlocks] != N);
    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);
    while(M--)
    {
        int t, P, S;
        fin >> t;
        if(t == 1)
        {
            fin >> P >> S;
            update(Left[P], Right[P], S);
        }
        else
        {
            fin >> S;
            fout << query(S) << "\n";
        }
    }
    return 0;
}