Cod sursa(job #460724)

Utilizator vladiiIonescu Vlad vladii Data 3 iunie 2010 17:57:56
Problema Arbore Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <iostream>
#include <vector>
#include <bitset>
#include <math.h>
using namespace std;
#define maxn 100010
#define maxsum 1000010
#define PB push_back
#define MP make_pair

int N, Q, K, F[maxn], H[maxn], L[maxn], v[maxn];
int rad, last, value[maxn], adunat[350];
vector<int> G[maxn];
vector<pair<int, int> > B;
bitset<maxsum> P[350];

void Euler(int nod) {
    v[nod] = 1;
    K++;
    F[nod] = K;
    H[K] = nod;
    for(vector<int>::iterator it=G[nod].begin(); it!=G[nod].end(); it++) {
         if(!v[*it]) {
              Euler(*it);
         }
    }
    L[nod] = K;
}   

void update(int start, int finish, int sum) {
    int i, j, p;
    for(i=1; i<B.size(); i++) {
         if((B[i].first < start || B[i].first == start) && (finish < B[i].second || finish == B[i].second)) {
              for(j=start; j<=finish; j++) {
                   P[i][ value[j] ] = 0;
                   value[j] += sum;
              }
              for(j=B[i].first; j<=B[i].second; j++) {
                   P[i][ value[j] ] = 1;
              }
              return;
         }
    }
    for(i=1; i<B.size(); i++) {
         if(B[i].first <= start && start <= B[i].second) {
              for(j=start; j<=B[i].second; j++) {
                   P[i][ value[j] ] = 0;
                   value[j] += sum;
              }
              for(j=start; j<=B[i].second; j++) {
                   P[i][ value[j] ] = 1;
              }
         }
         else if(B[i].first <= finish && finish <= B[i].second) {
              for(j=B[i].first; j<=finish; j++) {
                   P[i][ value[j] ] = 0;
                   value[j] += sum;
              }
              for(j=B[i].first; j<=finish; j++) {
                   P[i][ value[j] ] = 1;
              }
         }
         else if(start <= B[i].first && B[i].second <= finish) {
              adunat[i] += sum;
         }
    }
}

int query(int sum) {
    int i, j, p;
    for(i=1; i<B.size(); i++) {
         p = sum - adunat[i];
         if(p >= 0) {
              if(P[i][p] == 1) {
                   for(j=B[i].first; j<=B[i].second; j++) {
                        if(value[j] == p) {
                             return H[j];
                        }
                   }
              }
         }
    }
    return -1;
}

int main() {
    FILE *f1=fopen("arbore.in", "r"), *f2=fopen("arbore.out", "w");
    int i, x, t, s, p, q;
    fscanf(f1, "%d %d\n", &N, &Q);
    for(i=1; i<N; i++) {
         fscanf(f1, "%d %d\n", &p, &q);
         G[p].PB(q); G[q].PB(p);
    }
    
    Euler(1);
    
    //am rad bucati de lungime rad (p*rad + 1, (p+1)*rad)
    //si o bucata de lungime last la sfirsit
    rad = (int)sqrt(N);
    int nrrad = N / rad;
    last = N - rad * nrrad;
    
    B.PB( MP(0, 0) );
    for(i=0; i<nrrad; i++) {
         B.PB( MP(rad*i + 1, rad*(i+1)) );
    }
    if(last) {
         B.PB( MP(nrrad*rad+1, nrrad*rad+last) );
    }
    for(i=1; i<B.size(); i++) {
         P[i][0] = 1;
    }
    while(Q--) {
         fscanf(f1, "%d", &t);
         if(t==1) {
              fscanf(f1, "%d %d\n", &x, &s);
              //adun pe intervalul F[x], L[x] suma s
              update(F[x], L[x], s);
         }
         else {
              fscanf(f1, "%d\n", &s);
              p = query(s);
              fprintf(f2, "%d\n", p);
         }
    }
    
    fclose(f1); fclose(f2);
    return 0;
}