Cod sursa(job #904062)

Utilizator danalex97Dan H Alexandru danalex97 Data 3 martie 2013 18:00:45
Problema Arbore Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <cmath>
using namespace std;

ifstream F("arbore.in");
ofstream G("arbore.out");

const int Smax = 320;
const int Nmax = 102400;

const int Vmax = 1000002;
const int Sup = 1000000;

int A[Nmax],S[Smax];
bitset<Vmax> P[Smax];

vector<int> V[Nmax];
int Stop[Nmax],Start[Nmax];
int N,M,Co,step,Norm[Nmax];

#define IT(type) vector<type>::iterator

void Get(int Nod,int Dad)
{
    Start[Nod] = ++Co;
    Norm[Co] = Nod;

    for (IT(int) it=V[Nod].begin();it!=V[Nod].end();++it)
        if ( *it != Dad )
            Get( *it,Nod );

    Stop[Nod] = Co;
}

void Update(int nod,int sum)
{
    int st = Start[nod];
    int dr = Stop[nod];

    int start = ( (st-1) / step ) + 1;
    int stop = ( (dr-1) / step ) + 1;

    for (int i=start;i<=stop;++i)
    {
        int i3=(i-1)*step+1;
        int i4=i*step;

        if ( st <= i3 && i4 <= dr )
            S[i] += sum;
        else
        {
            int i1,i2;

            if ( st >= i3 && dr <= i4 )
                i1 = st , i2 = dr;
            else
            {
                if ( st < i3 && dr <= i4 )
                    i1 = i3 , i2 = dr;
                else
                    i1 = st , i2 = i4;
            }

            for (int j=i3;j<=i4;++j)
                P[i][A[j]] = 0;
            for (int j=i1;j<=i2;++j)
                A[j] += sum;
            for (int j=i3;j<=i4;++j)
                P[i][A[j]] = 1;
        }
    }
}

int Query(int sum)
{
    int start = 1;
    int stop = ( (N-1) / step ) + 1;

    for (int i=start;i<=stop;++i)
    {
        int what = sum-S[i];
        if ( what >= 0 && what <= Sup )
            if ( P[i][what] == 1 )
            {
                int i3=(i-1)*step+1;
                int i4=i*step;
                for (int j=i3;j<=i4;++j)
                    if ( A[j] == what )
                        return Norm[j];
            }
    }
    return -1;
}

int main()
{
    F>>N>>M;
    step = int(sqrt(double(N)));

    int start = 1;
    int stop = ( (N-1) / step ) + 1;
    for (int i=start;i<=stop;++i)
        P[i][0] = 1;

    for (int i=1,a,b;i<N;++i)
    {
        F>>a>>b;
        V[a].push_back(b);
        V[b].push_back(a);
    }
    Get( 1 , 0 );

    for (int i=1,type,nod,sum;i<=M;++i)
    {
        F>>type;
        if ( type == 1 )
        {
            F>>nod>>sum;
            Update(nod,sum);
        }
        else
        {
            F>>sum;
            G<<Query(sum)<<'\n';
        }
    }
}