Cod sursa(job #960626)

Utilizator primulDarie Sergiu primul Data 10 iunie 2013 20:31:17
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.22 kb
#include <fstream>
#include <algorithm>
#include <list>
#include <vector>
 
using namespace std;
 
ifstream fin("arbore.in");
ofstream fout("arbore.out");
 
char parse[100000], *now;
inline void verify()
{
    if (*now == 0)
    {
        fin.get(parse, sizeof(parse), '\0');
        now = parse;
    }
}
int get()
{
    while (*now < '0' || *now > '9')
    {
        ++now;
        verify();
    }
    int num = 0;
    while (*now >= '0' && *now <= '9')
    {
        num = num * 10 + (*now - '0');
        ++now;
        verify();
    }
    return num;
}
 
const int MOD = 256;
vector<int> HASH[350][MOD];
 
void h_add(int w, int x)
{
    unsigned char val = x;
    for (vector<int>::iterator it = HASH[w][val].begin(); it != HASH[w][val].end(); ++it)
        if (*it == x)
            return;
    HASH[w][val].push_back(x);
}
void h_erase(int w, int x)
{
    unsigned char val = x;
    HASH[w][val].clear();
}
bool h_find(int w, int x)
{
    unsigned char val = x;
    for (vector<int>::iterator it = HASH[w][val].begin(); it != HASH[w][val].end(); ++it)
        if (*it == x)
            return true;
    return false;
}
 
int N, Q;
vector<int> V[100002];
bool S[100002];
int in[100002], out[100002];
int nod[100002], val[100002], add[350];
int sorted[100002];
int bucket;
 
void Dfs(int x)
{
    S[x] = true;
    nod[++nod[0]] = x;
    in[x] = nod[0];
 
    for (vector<int>::iterator it = V[x].begin(); it != V[x].end(); ++it)
        if (!S[*it])
            Dfs(*it);
 
    out[x] = nod[0];
}
 
int main()
{
    now = parse;
    verify();
 
    N = get();
    Q = get();
    for (int i = 1, nod1, nod2; i <= N - 1; ++i)
    {
        nod1 = get();
        nod2 = get();
        V[nod1].push_back(nod2);
        V[nod2].push_back(nod1);
    }
    Dfs(1);
 
    for (; bucket * bucket < N; ++bucket);
    for (int i = 1, b = 1; i <= N; i += bucket, ++b)
        h_add(b, 0);
 
    for (int i = 1, type, valn, nodn; i <= Q; ++i)
    {
        type = get();
        if (type == 1)
        {
            nodn = get();
            valn = get();
 
            int pos1 = in[nodn], pos2 = out[nodn];
            for (int i = 1, b = 1; i <= N; i += bucket, ++b)
            {
                if (pos1 >= i && pos1 < i + bucket && pos2 >= i + bucket)
                {
                    for (int j = pos1; j <= N && j <= i + bucket - 1; ++j)
                    {
                        h_erase(b, val[j]);
                        val[j] += valn;
                    }
                    for (int j = i; j <= N && j <= i + bucket - 1; ++j)
                        h_add(b, val[j]);
                }
                else if (pos1 >= i && pos2 < i + bucket)
                {
                    for (int j = pos1; j <= pos2; ++j)
                    {
                        h_erase(b, val[j]);
                        val[j] += valn;
                    }
                    for (int j = i; j <= N && j <= i + bucket - 1; ++j)
                        h_add(b, val[j]);
                }
                else if (pos2 >= i && pos2 < i + bucket)
                {
                    for (int j = i; j <= pos2; ++j)
                    {
                        h_erase(b, val[j]);
                        val[j] += valn;
                    }
                    for (int j = i; j <= N && j <= i + bucket - 1; ++j)
                        h_add(b, val[j]);
                }
                else if (pos1 <= i && pos2 >= i + bucket)
                    add[b] += valn;
 
            }
        }
        else
        {
            valn = get();
 
            bool found = false;
            for (int i = 1, b = 1; i <= N; i += bucket, ++b)
                if (h_find(b, valn - add[b]))
                {
                    for (int j = i; j <= N && j <= i + bucket - 1; ++j)
                        if (val[j] == valn - add[b])
                        {
                            fout << nod[j] << '\n';
                            break;
                        }
 
                    found = true;
                    break;
                }
 
            if (!found) fout << -1 << '\n';
        }
    }
 
    fin.close();
    fout.close();
}