Cod sursa(job #2743)

Utilizator filipbFilip Cristian Buruiana filipb Data 18 decembrie 2006 18:57:19
Problema Arbore Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <stdio.h>
#include <stdlib.h>
#define NMax 100024
#define BITI 30
#define SQRT_MAX 340
typedef struct lista { int id; struct lista *next; } lista;
typedef lista *Graf[NMax];

int N, M, e[NMax], fst[NMax], lst[NMax], uz[NMax], h = 0, SQRT;
int S[SQRT_MAX], real[NMax], U[SQRT_MAX][33335];
Graf G;

void add_to_list(lista **l, int item)
{
     lista *tmp = (lista *)malloc(sizeof(lista));
     
     tmp->id = item;
     tmp->next = *l;
     *l = tmp;
}

void dfs(int nod)
{
     lista *f;
     
     uz[nod] = 1; e[h] = nod; fst[nod] = (h++);
     for (f = G[nod]; f; f = f->next)
         if (!uz[f->id])
            dfs(f->id);
     lst[nod] = h;
}

int bit(int i, int nr_b)
{
    int octet = nr_b / BITI, nr_bit = nr_b % BITI;
    
    return ( U[i][octet] & (1<<nr_bit) ) != 0;
}

void set_bit(int i, int nr_b, int tip)
{
    int octet = nr_b / BITI, nr_bit = nr_b % BITI;
        
    if (tip) // deselectare
        if ( ( U[i][octet] & (1<<nr_bit) ) != 0 )
        {   U[i][octet] -= (1<<nr_bit); return ; }
    
    if ( ( U[i][octet] & (1<<nr_bit) ) == 0 ) // selectare
       U[i][octet] += (1<<nr_bit);
}

void update(int lo, int hi, int x)
{
     int i, j, to, fr, up, down;

     down = lo; up = hi;
     
     // 1st
     for (i = down/SQRT, j = i * SQRT; j < (i+1) * SQRT && j < N; j++)
         set_bit(i, real[j], 1);
     for (i = lo/SQRT, to = (i+1) * SQRT; lo <= hi && lo < to; lo++)
         real[lo] += x;
     for (i = down/SQRT, j = i * SQRT; j < (i+1) * SQRT; j++)
         set_bit(i, real[j], 0);
     
          
     // 2nd
     for (i = lo/SQRT+1; i <= hi/SQRT-1; i++, lo += SQRT) S[i] += x;      
     
     // 3rd
     for (i = up/SQRT, j = i * SQRT; j < (i+1) * SQRT && j < N; j++)
         set_bit(i, real[j], 1);
          
     for (; lo <= hi; lo++)
         real[lo] += x;

     for (i = up/SQRT, j = i * SQRT; j < (i+1) * SQRT && j < N; j++)
         set_bit(i, real[j], 0);
                
}

int query(int x)
{
     int i, j, to;
     
     for (i = j = 0; i < N; i+=SQRT, j++)
     {
         if (x < S[j] || !bit(j, x-S[j])) continue;
         for (i = j*SQRT, to = (j+1)*SQRT; i < to && i < N; i++)
             if (S[j] + real[i] == x)
                return e[i];
     }
     
     return -1;  
}

int main(void)
{
    int i, j, p, q, tp;
    
    freopen("arbore.in", "r", stdin);
    freopen("arbore.out", "w", stdout);
  
    scanf("%d %d", &N, &M);
    for (i = 1; i <= N; i++) G[i] = NULL;
    for (i = 1; i < N; i++)
    {
        scanf("%d %d", &p, &q);
        add_to_list(&G[p], q);
        add_to_list(&G[q], p);
    }
    
    dfs(1);
        
    for (SQRT = 1; SQRT * SQRT < N; SQRT++);
    for (i = j = 0; j < N; i++, j += SQRT) 
        set_bit(i, 0, 0);
            
    for (i = 1; i <= M; i++)
    {
        scanf("%d", &tp);
        if (tp == 1)
        {
           scanf("%d %d", &p, &q);
           update(fst[p], lst[p]-1, q);
        }
        else if (tp == 2)
        {
           scanf("%d", &p);
           printf("%d\n", query(p));  
        }
        
    }
        
    return 0;
}