Cod sursa(job #1328135)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 28 ianuarie 2015 01:25:57
Problema Arbore Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.5 kb
#include <fstream>
#include <vector>
#include <utility>
#include <cmath>
#include <list>
#include <tr1/unordered_map>
#include <tr1/unordered_set>

#define NMAX 100000
#define RADMAX 405
using namespace std;
using namespace tr1;

int n;
vector<int> graf[NMAX+5];

int poz;
int parc[NMAX+5];
int first[NMAX+5];
int last[NMAX+5];

void dfs (int nod, int father) {
    parc[++poz]=nod;
    first[nod]=poz;
    for(vector<int>::iterator it=graf[nod].begin();it!=graf[nod].end();it++)
        if(*it!=father)
            dfs(*it,nod);
    last[nod]=poz;
}

/*#define mod 26017
list<pair<int,int> > hashes[RADMAX][mod];

inline void insert (int h, int x, int poz) {
    int b=x%mod;

    for(list<pair<int,int> >::iterator it=hashes[h][b].begin();it!=hashes[h][b].end();it++)
        if((*it)==make_pair(x,poz))
            return;

    hashes[h][b].push_back(make_pair(x,poz));
}

inline int find (int h, int x) {
    int b=x%mod;

    for(list<pair<int,int> >::iterator it=hashes[h][b].begin();it!=hashes[h][b].end();it++)
        if(it->first==x)
            return it->second;
    return -1;
}

inline void del (int h, int x, int poz) {
    int b=x%mod;

    for(list<pair<int,int> >::iterator it=hashes[h][b].begin();it!=hashes[h][b].end();it++)
        if(*it==make_pair(x,poz)) {
            hashes[h][b].erase(it);
            return;
        }
}*/

unordered_map<int,unordered_set<int> > hashes[NMAX];

int rad;
int lazy[RADMAX];

int sir[NMAX+5];

inline void f_insert (int bucata, int val, int poz) {
    if(hashes[bucata][val].find(poz)==hashes[bucata][val].end())
        hashes[bucata][val].insert(poz);
}

inline void f_del (int bucata, int val, int poz) {
    unordered_set<int>::iterator it=hashes[bucata][val].find(poz);

    if(it!=hashes[bucata][val].end())
        hashes[bucata][val].erase(it);
}

inline int f_find (int bucata, int val) {
    if(!hashes[bucata][val].size())
        return -1;
    else
        return (*hashes[bucata][val].begin());
}

inline void update (int st, int dr, int val) {
    int bst=(st-1)/rad+1;
    int bdr=(dr-1)/rad+1;

    if(bst==bdr)
        for(int i=st;i<=dr;i++) {
            f_del(bst,sir[i],i);
            f_insert(bst,sir[i]+val,i);

            sir[i]+=val;
        }
    else {
        for(int i=bst+1;i<bdr;i++)
            lazy[i]+=val;

        for(int i=st;i<=bst*rad;i++) {
            f_del(bst,sir[i],i);
            f_insert(bst,sir[i]+val,i);

            sir[i]+=val;
        }

        for(int i=(bdr-1)*rad+1;i<=dr;i++) {
            f_del(bdr,sir[i],i);
            f_insert(bdr,sir[i]+val,i);

            sir[i]+=val;
        }
    }
}

inline int query (int sum) {
    int aux;
    for(int i=1;i<=(n-1)/rad+1;i++) {
        aux=f_find(i,sum-lazy[i]);
        if(aux!=-1)
            return parc[aux];
    }

    return -1;
}

int main()
{
    ifstream cin("arbore.in");
    ofstream cout("arbore.out");

    int m=0;
    cin>>n>>m;

    rad=sqrt(n);

    int a,b;
    for(int i=1;i<n;i++) {
        cin>>a>>b;
        graf[a].push_back(b);
        graf[b].push_back(a);
    }

    dfs(1,0);

    for(int i=1;i<=n;i++)
        f_insert((i-1)/rad+1,0,i);

    int tip,p,s;
    while(m--) {
        cin>>tip;

        if(tip==1) {
            cin>>p>>s;

            update(first[p],last[p],s);
        }
        else {
            cin>>s;
            cout<<query(s)<<'\n';
        }
    }

    cin.close();
    cout.close();
    return 0;
}