Cod sursa(job #1346603)

Utilizator irimiecIrimie Catalin irimiec Data 18 februarie 2015 13:58:27
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.41 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 << ":";
    if((x1-1) % sqrtn != 0)
        for(; (x1-1) % sqrtn != 0; x1++) {
            A[x1] += sum;
            MAXIM[x1/sqrtn] = max(A[x1] + B[x1/sqrtn], MAXIM[x1/sqrtn]);
        }
    for(; x2 % sqrtn != 0; x2--) {
        A[x2] += sum;
        MAXIM[x2/sqrtn] = max(A[x2] + B[x2/sqrtn], MAXIM[x2/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(0);
    lin.pb(1);
    dfs(1);

    /*for(int i = 1; i <= n; ++i)
        cout << lin[i] << " ";
    cout << "\n";*/

    //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, ang[angajat1].sc, sumaprimita);
        } else {
            f >> sumaprimita;
            g << search(sumaprimita) << "\n";
        }

    }
    return 0;
}