Cod sursa(job #1154490)

Utilizator alexalghisiAlghisi Alessandro Paolo alexalghisi Data 26 martie 2014 10:47:13
Problema Arbore Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <iostream>
#include <fstream>
#include <bitset>
#include <cmath>
#include <vector>

#define DN 100005
#define DM 333
#define pb push_back
#define next_nod list[nod][i]
#define low(x) (len*(x-1) + 1)
#define high(x) (len*x)
using namespace std;

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

vector < int > list[DN];
bitset < DN > viz,in_buc[DM];

int n,m,st[DN],dr[DN],sz,len,sum_buc[DM],elem[DN],mp[DN];

void read(){

    f>>n>>m;
    len = sqrt(n);

    for(int i=1;i<n;++i){

        int a,b;
        f>>a>>b;
        list[a].pb(b);
        list[b].pb(a);
    }
}


void dfs(int nod){

    viz[ nod ] = true;
    st[nod] = ++sz;
    mp[ sz ] = nod;
    for(int i=0;i<list[nod].size();++i)
        if(!viz[next_nod])
            dfs(next_nod);
    dr[nod] = sz;
}

int find_buc(int poz){

    if( poz % len == 0)
        return poz/len;
    return poz/len + 1;
}

void update_buc(int buc,int a,int b,int s){

    int st = max(a,low(buc));
    int dr = min(b,high(buc));

    for(int i = low(buc); i <= high(buc) ; ++i)
        in_buc[ buc ][ elem[i] ] = 0;

    for(int i = st; i <= dr ; ++i)
        elem[i]+=s;

    for(int i = low(buc); i <= high(buc) ; ++i)
        in_buc[ buc ][ elem[i] ] = 1;
}

void update(int a,int b,int s){

    //cout<<a<<" "<<b<<" += "<<s<<endl;

    for(int i = find_buc(a) ; i <= find_buc(b); ++i){

        if( a <= low(i) && high(i)<=b ) /// am toata bucata in interiorul updateului
            sum_buc[i]+=s;
        else
            if( a > low(i) && a <= high(i) ) /// ( ... a ..]
                update_buc(i,a,b,s);
        else
            if( b >= low(i) && b < high(i)) /// [ .. b .. )
                update_buc(i,a,b,s);
    }
}

void init(){

    for(int i=1;i<=find_buc(n);++i)
        in_buc[i][0] = 1;
}

int query(int s){

    for(int i=1;i<=find_buc(n);++i)
        if( sum_buc[i] <=s && in_buc[i][ s - sum_buc[i]] ){

            for(int j = low(i); j <= high(i) ; ++j)
                if( elem[j] + sum_buc[i] == s)
                    return mp[j];
        }
    return -1;
}


void solve(){

    dfs(1);
    init();

  //  for(int i=1;i<=n;++i)
    //    cout<<i<<" "<<st[i]<<" "<<dr[i]<<endl;
    for(;m--;){

        int op;
        f>>op;
        if(op == 1){

            int p,s;
            f>>p>>s;
            //cout<<" NOD :"<<p<<" st : "<< st[p]<<endl;
            update(st[p],dr[p],s);
        }else{

            int s;
            f>>s;
            g<<query(s)<<"\n";
        }
    }
}



int main()
{
    read();
    solve();

    return 0;
}