Cod sursa(job #36609)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 23 martie 2007 19:21:24
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.64 kb
#include <stdio.h>
#include <vector>
#define NMAX 100100
#define TMAX (1<<17)
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))

using namespace std;
vector<int> A[NMAX];
int Renum[NMAX], N, num, Spot[NMAX], X, Y, T[2*TMAX], M, V[NMAX][2], SMAX;

void dfs(int i)
{
        int j, n = A[i].size();
        
        Spot[i] = 1;
        for (j = 0; j < n; j++)
            if (Spot[ A[i][j] ] == 0)
            {
                dfs(A[i][j]);
                Renum[ A[i][j] ] = ++num;
            }
}

void update(int p1, int p2, int node, int sum)
{
        int mij = (p1+p2)>>1;

        if (X <= p1 && p2 <= Y)
        {
                T[node] += sum;
                SMAX = MAX(SMAX, T[node]);
                return;
        }
        if ( (p1 <= X && X <= p2) || (p1 <= Y && Y <= p2) )
        {
                update(p1, mij-1, node<<1, sum);
                update(mij, p2, (node<<1)+1, sum);
        }
}

int query(int x)
{
        int node = TMAX+x, rez = 0;

        rez += T[node];
        while (node > 1)
        {
                node = node>>1;
                rez += T[node];
        }
        return rez;
}

void compute(int i)
{
        int j, n = A[i].size();

        Spot[i] = 1;
        for (j = 0; j < n; j++)
            if (Spot[ A[i][j] ] == 0)
            {
                compute(A[i][j]);
                V[i][0] = MIN(V[i][0], V[ A[i][j] ][0]);
                V[i][1] = MAX(V[i][1], V[ A[i][j] ][1]);
            }
}

int main()
{
        int i, j, k, task, node, sum;

        freopen("arbore.in", "r", stdin);
        scanf("%d %d", &N, &M);

        for (k = 1; k < N; k++)
        {
                scanf("%d %d", &i, &j);
                A[i].push_back(j); A[j].push_back(i);
        }

        dfs(1);
        Renum[1] = ++num;
        for (i = 0; i < NMAX; i++) Spot[i] = 0;
        for (i = 1; i <= N; i++) V[i][0] = V[i][1] = Renum[i];
        compute(1);

        if (num > N) return 1;

        freopen("arbore.out", "w", stdout);
        while (M--)
        {
                scanf("%d", &task);
                if (task==1) { scanf("%d %d", &node, &sum);
                    X = V[node][0]; Y = V[node][1];
                    if (X < N || Y < N || 1 > X || 1 > Y) return 1;
                    update(0, TMAX-1, 1, sum); }
                else { scanf("%d", &sum);
                if (sum > SMAX) printf("-1\n");
                else
                for (i = 1; i <= N; i++)
                {
                    if (query(Renum[i]) == sum) {printf("%d\n", i); break;} }
                }
        }

        return 0;

}