Cod sursa(job #1219887)

Utilizator mariusn01Marius Nicoli mariusn01 Data 15 august 2014 15:57:50
Problema Arbore Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <algorithm>

#define DIM 10010
#define RAD 320

using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
int Add[RAD];  // cat s-a adunat la fiecare numar din intervalul reprezentat de indice
int A[DIM];    // cat s-a adunat la fiecare numar, in afara de ce e in ADD (valoarea reala a numarului i este A[i] + ADD[intervalul de radical al lui i])
bitset<DIM> viz;
bitset<1000010> P[RAD];
int Begin[DIM], End[DIM], poz[DIM];
vector<int> L[DIM];
int g, n, i, j, q, x, y, t, p, s;

inline int getRad(int x) {
    return (x/RAD);
}

inline int getFirst(int r) {
    return (r*RAD);
}

inline int getLast(int r) {
    return ((r+1)*RAD-1);
}

void dfs(int nod) {
    g++;
    Begin[nod] = g;
    viz[nod] = 1;
    poz[g] = nod;
    for (int i=0;i<L[nod].size();i++) {
        if (!viz[ L[nod][i] ])
            dfs(L[nod][i]);
    }
    End[nod] = g;
}

void update(int st, int dr, int s) {
    // toate valorile dintre pozitiile st si dr vor creste cu s
    int r1 = getRad(st);
    int r2 = getRad(dr);
    for (int i=r1;i<=r2;i++) {
        if (getFirst(i) >= st && getLast(i)<=dr) {
            // fac update pe toata bucata de radical
            Add[i] += s;
            continue;
        }

        if (st <= getLast(i) || dr>= getFirst(i)) {
            int first = getFirst(i);
            int last = getLast(i);
            if (st >= first)
                first = st;

            if (dr <= last)
                last = dr;

            for (int j = getFirst(i); j<=getLast(i); j++) {
                A[j] += Add[i];
                if (j >= first && j<=last)
                    A[j] += s;
                if (A[j])
                    P[i][ A[j] ] = 1;
            }
            Add[i] = 0;
            continue;
        }
    }
}

int query(int s) {
    for (int i=0;i<RAD;i++) {
        if (P[i][s]) {
            for (j=getFirst(i); j<=getLast(i); j++) {
                if (A[j] + Add[i] == s) {
                    return poz[ j ];
                }
            }
        }
    }
    return -1;
}

int main() {
    fin>>n>>q;
    for (i=1;i<n;i++) {
        fin>>x>>y;
        L[x].push_back(y);
        L[y].push_back(x);
    }

    for (i=1;i<=n;i++)
        sort(L[i].begin(), L[i].end());

    g = -1;
    dfs(1);
    for (;q--;) {
        fin>>t;
        if (t == 1) {
            fin>>p>>s;
            update(Begin[p], End[p], s);
        } else {
            fin>>s;
            fout<<query(s)<<"\n";
        }
    }

    return 0;
}