Cod sursa(job #931148)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 28 martie 2013 00:10:50
Problema Arbore Scor 85
Compilator cpp Status done
Runda Lista lui wefgef Marime 3.61 kb
#include <fstream>
#include <vector>
#include <cstdio>
#include <bitset>
#define SQ 330
#define VM 1000010
#define NM 100010

using namespace std;

FILE* fin=fopen("arbore.in","r");
FILE* fout=fopen("arbore.out","w");
const int maxb=1000000;
char buf[maxb];
int ptr=0;

inline int GetInt()
{
    int nr=0;
    while(buf[ptr]<'0'||'9'<buf[ptr])
        if (++ptr>=maxb) fread(buf,1,maxb,fin),ptr=0;
    while ('0'<=buf[ptr]&&buf[ptr]<='9')
    {
        nr=nr*10+buf[ptr]-'0';
        if (++ptr>=maxb) fread(buf,1,maxb,fin),ptr=0;
    }
    return nr;
}

int N, M, K;
int First[NM], Last[NM];
int Inverse[NM];
vector<int> G[NM];
int V[NM], ListVal[SQ];
int NoLists, SizeS;
int Left[SQ], Right[SQ];
bitset<VM> ListSums[SQ];
int Poz[VM];

void Read ()
{
    N=GetInt();
    M=GetInt();

    for (int i=1; i<N; i++)
    {
        int a=GetInt(), b=GetInt();
        G[a].push_back(b);
        G[b].push_back(a);
    }
}

void DF (int Node)
{
    First[Node]=++K;
    Inverse[K]=Node;

    for (vector<int>::iterator it=G[Node].begin(); it!=G[Node].end(); ++it)
        if (First[*it]==0)
            DF(*it);

    Last[Node]=K;
}

void BuildLists()
{
    for (SizeS=1; SizeS*SizeS<=N; ++SizeS);
    --SizeS;

    for (int i=1; i<=N;)
    {
        ++NoLists;
        Left[NoLists]=i;
        Right[NoLists]=min(i+SizeS-1, N);
        ListSums[NoLists][0]=1;
        i+=SizeS;
    }
}

int SearchLeft (int X)
{
    int P=1, U=NoLists, M, ANS=1;

    while (P<=U)
    {
        M=(P+U)/2;

        if (Left[M]<=X)
        {
            ANS=M;
            P=M+1;
        }
        else
            U=M-1;
    }

    return ANS;
}

int SearchRight (int X)
{
    int P=1, U=NoLists, M, ANS=1;

    while (P<=U)
    {
        M=(P+U)/2;

        if (Right[M]>=X)
        {
            ANS=M;
            U=M-1;
        }
        else
            P=M+1;
    }

    return ANS;
}

inline void Update (int L, int R, int S)
{
    int Llim=SearchLeft(L);
    int Rlim=SearchRight(R);
    for (int i=Llim; i<=Rlim; i++)
    {
        if (L<=Left[i] && Right[i]<=R)
        {
            ListVal[i]+=S;
            continue;
        }

        for (int j=Left[i]; j<=Right[i]; j++)
        {
            ListSums[i][V[j]]=0;
            if (Poz[V[j]]==i) Poz[V[j]]=i;
            V[j]+=ListVal[i] + (L<=j && j<=R?S:0);
        }

        ListVal[i]=0;
        for (int j=Left[i]; j<=Right[i]; j++)
        {
            Poz[V[j]]=i;
            ListSums[i][V[j]]=1;
        }
    }
}

inline int Query (int S)
{
    int i=Poz[S];
    if (i!=0 && S>ListVal[i] && ListSums[i][S-ListVal[i]]==1)
    {
        S-=ListVal[i];
        for (int j=Left[i]; j<=Right[i]; j++)
            if (V[j]==S)
                return Inverse[j];
    }

    for (i=1; i<=NoLists; i++)
    {
        if (S<ListVal[i])
            continue;

        if (ListSums[i][S-ListVal[i]]==1)
        {
            S-=ListVal[i];
            for (int j=Left[i]; j<=Right[i]; j++)
                if (V[j]==S)
                    return Inverse[j];
        }
    }

    return -1;
}

void Solve ()
{
    for (int i=1; i<=M; i++)
    {
        int t=GetInt();

        if (t==1)
        {
            int p=GetInt();
            int s=GetInt();

            Update(First[p], Last[p], s);
        }
        else
        {
            int s=GetInt();

            fprintf(fout, "%d\n", Query(s));
        }
    }
}

int main ()
{
    Read();
    DF(1);
    BuildLists();
    Solve();

    fclose(fin);
    fclose(fout);

    return 0;
}