Cod sursa(job #1556736)

Utilizator tudi98Cozma Tudor tudi98 Data 25 decembrie 2015 19:21:06
Problema Arbore Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define Nmax 100000
#define sqrtNmax 317

int N,M,id = 0,sqn,B;
vector<int> G[Nmax+1];
int start[Nmax+1],finish[Nmax+1],p[Nmax+1];
bool seen[Nmax+1],have[sqrtNmax+1][1000001];
int Add[sqrtNmax+1], A[Nmax+1];

inline int block(int pos)
{
    if (pos % sqn == 0) return pos / sqn;
    else return pos / sqn + 1;
}

void dfs(int node)
{
    seen[node] = 1;
    start[node] = ++id;
    p[id] = node;
    for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); ++it)
        if (!seen[*it])
            dfs(*it);
    finish[node] = id;
}

void updateBlock(int b)
{
    for (int i = (b-1)*sqn+1; i <= b*sqn; i++)
        have[b][A[i]] = 1;
}

void Update(int node,int sum)
{
    int block1 = block(start[node]), block2 = block(finish[node]), i;
    for (i = start[node]; block(i) == block1 && i <= finish[node]; ++i)
        A[i] += sum, have[block1][A[i]-sum] = 0;
    updateBlock(block1);
    for (block1 = block1 + 1; block1 < block2; ++block1)
        Add[block1] += sum;
    if (block(start[node]) == block2) return;
    for (i = (block2 - 1) * sqn + 1; i <= finish[node]; i++)
        A[i] += sum, have[block2][A[i]-sum] = 0;
    updateBlock(block2);
}

int getNode(int b,int sum)
{
    for (int i = (b-1)*sqn+1; i <= b*sqn; i++)
        if (A[i] == sum) return p[i];
    return 0;
}

int Query(int sum)
{
    for (int b = 1; b <= B; b++)
        if (have[b][sum - Add[b]] && sum-Add[b] >= 0) return getNode(b,sum-Add[b]);
    return -1;
}

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

    fin >> N >> M;
    int a,b;
    for (int i = 1; i < N; i++)
    {
        fin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    dfs(1);
    sqn = (int)sqrt((double)N);
    B = N / sqn;
    if (N % sqn != 0) ++B;

    for (int i = 0; i <= B; i++)
        have[i][0] = 1;

    int x,y,z;
    for (int i = 1; i <= M; i++)
    {
        fin >> x;
        if (x == 1)
        {
            fin >> y >> z;
            Update(y,z);
        }
        else
        {
            fin >> z;
            fout << Query(z) << "\n";
        }
    }
}