Cod sursa(job #1329102)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 29 ianuarie 2015 00:59:44
Problema Arbore Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.57 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <list>
#include <tr1/unordered_map>
//#include <tr1/unordered_set>
//#include <map>
//#include <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];
//map<int,set<int> > hashes[NMAX];

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

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

    if(it->second.empty())
        hashes[bucata].erase(it);
}

inline int f_find (int bucata, int val) {
    unordered_map<int,unordered_set<int> >::iterator it=hashes[bucata].find(val);
    if(it==hashes[bucata].end())
        return -1;
    else
        return (*it->second.begin());
}*/

int rad;
int lazy[RADMAX];

int sir[NMAX+5];

unordered_map<int,int> hashes[NMAX];

inline void f_insert (int bucata, int val) {
    hashes[bucata][val]++;
}

inline void f_del (int bucata, int val) {
    int x=hashes[bucata][val]--;

    if(x==0)
        hashes[bucata].erase(val);
}

inline bool f_find (int bucata, int val) {
    return (hashes[bucata].find(val)!=hashes[bucata].end());
}

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]);
            f_insert(bst,sir[i]+val);

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

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

            sir[i]+=val;
        }

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

            sir[i]+=val;
        }
    }
}

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

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

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

    rad=min((int)(1*sqrt(n)),n);
    //cout<<rad<<endl;

    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);

    //for(int i=1;i<=(n-1)/rad+1;i++) {
    //    hashes[i].reserve(1000000);
    //}

    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';
        }
    }

    //int sz=0;
    //for(int i=1;i<=(n-1)/rad+1;i++)
    //    sz+=hashes[i].size();
    //cout<<sz<<endl;

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