Cod sursa(job #1401648)

Utilizator Ionut228Ionut Calofir Ionut228 Data 26 martie 2015 00:54:12
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

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

int N, M, K, lim;
int el[100005], sumBucket[350];
int first[100005], last[100005], nod_from_pos[100005];
vector<int> V[100005];
bool inBucket[350][1000005];

struct buchete
{
    int lt, rt;
};
buchete buckets[350];

void dfs(int nod, int father)
{
    first[nod] = ++K;
    nod_from_pos[K] = nod;

    for (vector<int>::iterator it = V[nod].begin(); it != V[nod].end(); ++it)
        if (*it != father)
            dfs(*it, nod);

    last[nod] = K;
}

int getBucket(int x)
{
    if (x % lim == 0)
        return x / lim;
    return x / lim + 1;
}

void updateBucket(int start, int finish, int nowBucket, int s)
{
    for (int i = buckets[nowBucket].lt; i <= buckets[nowBucket].rt; ++i)
        inBucket[nowBucket][el[i]] = 0;
    for (int i = start; i <= finish; ++i)
        el[i] += s;
    for (int i = buckets[nowBucket].lt; i <= buckets[nowBucket].rt; ++i)
        inBucket[nowBucket][el[i]] = 1;
}

void update(int start, int finish, int s)
{
    for (int nowBucket = getBucket(start); nowBucket <= getBucket(finish); ++nowBucket)
    {
        if (start <= buckets[nowBucket].lt && buckets[nowBucket].rt <= finish)
            sumBucket[nowBucket] += s;
        else if (start > buckets[nowBucket].lt && buckets[nowBucket].rt <= finish)
            updateBucket(start, buckets[nowBucket].rt, nowBucket, s);
        else if (start <= buckets[nowBucket].lt && finish < buckets[nowBucket].rt)
            updateBucket(buckets[nowBucket].lt, finish, nowBucket, s);
        else if (start > buckets[nowBucket].lt && finish < buckets[nowBucket].rt)
            updateBucket(start, finish, nowBucket, s);
    }
}

int query(int s, int nBuckets)
{
    for (int nowBucket = 1; nowBucket <= nBuckets; ++nowBucket)
        if (sumBucket[nowBucket] <= s && inBucket[nowBucket][s - sumBucket[nowBucket]])
            for (int i = buckets[nowBucket].lt; i <= buckets[nowBucket].rt; ++i)
                if (el[i] == s - sumBucket[nowBucket])
                    return nod_from_pos[i];

    return -1;
}

int main()
{
    fin >> N >> M;
    lim = sqrt(double(N));
    for (int i = 1, nod1, nod2; i <= N - 1; ++i)
    {
        fin >> nod1 >> nod2;
        V[nod1].push_back(nod2);
        V[nod2].push_back(nod1);
    }

    dfs(1, 0);
    int pos = 1;
    for (int i = 1; i <= getBucket(N); ++i)
    {
        buckets[i].lt = pos;
        buckets[i - 1].rt = pos - 1;
        pos += lim;
    }
    buckets[getBucket(N)].rt = N;

    for (int i = 1; i <= getBucket(N); ++i)
        inBucket[i][0] = 1;

    while (M--)
    {
        int type, p, s;

        fin >> type;
        if (type == 1)
        {
            fin >> p >> s;
            update(first[p], last[p], s);
        }
        else if (type == 2)
        {
            fin >> s;
            fout << query(s, getBucket(N)) << '\n';
        }
    }

    fin.close();
    fout.close();
    return 0;
}