Cod sursa(job #1267016)

Utilizator irimiecIrimie Catalin irimiec Data 19 noiembrie 2014 13:49:49
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <cstring>
#define pb push_back
#define mp make_pair
#define fs first
#define sc second

using namespace std;

ifstream f("arbore.in");
ofstream g("arbore.out");

const int NMAX = 100001;
const int NMAXSQRT = 316;

int n, m, sqrtn;
int angajat1, angajat2;
int tip, sumaprimita, maxsum;
int A[NMAX], B[NMAXSQRT], MAXIM[NMAXSQRT];
vector<int> p[NMAX], lin;
pair<int, int> ang[NMAX];

void dfs(int x) {
    int aux = lin.size() - 1;
    for(int i = 0; i < p[x].size(); ++i) {
        lin.pb(p[x][i]);
        dfs(p[x][i]);
    }
    ang[x] = mp(aux, lin.size() - 1);
}

void update(int x1, int x2, int sum) {
    //cout << x1 << "," << x2 << ";" << ((x2-1) / sqrtn) * sqrtn << ":";
    for(int a1 = x1; a1 < ((x1) / sqrtn * sqrtn + 1); a1++) {
        A[a1] += sum;
        MAXIM[(a1-1)/sqrtn] = max(A[a1] + B[(a1-1)/sqrtn], MAXIM[(a1-1)/sqrtn]);
    }
    for(int a1 = x2; a1 > ((x2 - 1) / sqrtn + 1) * sqrtn; a1--) {
        A[a1] += sum;
        MAXIM[(a1-1)/sqrtn] = max(A[a1] + B[(a1-1)/sqrtn], MAXIM[(a1-1)/sqrtn]);
    }
    for(int a1 = x1 / sqrtn; a1 < x2 / sqrtn; a1++)
        B[a1] += sum, MAXIM[a1] += sum;
    /*for(int i = 1; i <= n; ++i)
        cout << A[i] + B[(i-1)/sqrtn]<< " ";
    cout << "- ";
    for(int i = 0; i <= sqrtn; ++i)
        cout << B[i]  << " ";
    cout << "\n";*/
}

int search(int x) {
    for(int i = 0; i <= sqrtn; ++i) {
        //g << MAXIM[i] << " ";
        if(MAXIM[i] < x)
            continue;
        for(int j = i * sqrtn; j <= (i+1) * sqrtn; ++j) {
            if(A[j] + B[i] == x && j > 0)
                return j;
        }
    }
    return -1;
}

int main() {
    f >> n >> m; sqrtn = sqrt(n);

    memset(MAXIM, 0, sizeof(MAXIM));

    for(int i = 1; i < n; ++i) {
        f >> angajat1 >> angajat2;
        p[angajat1].pb(angajat2);
    }
    lin.pb(1);
    dfs(1);

    //for(int i = 1; i <= n; ++i)
    //    cout << ang[i].fs+1 << " " << ang[i].sc+1 << "\n";

    while( m-- ) {
        f >> tip;
        if( tip == 1 ) {
            f >> angajat1 >> sumaprimita;
            update(ang[angajat1].fs+1, ang[angajat1].sc+1, sumaprimita);
        } else {
            f >> sumaprimita;
            g << search(sumaprimita) << "\n";
        }

    }
    return 0;
}