Cod sursa(job #611350)

Utilizator crushackPopescu Silviu crushack Data 1 septembrie 2011 02:02:15
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.58 kb
#include <stdio.h>
#include <vector>
#include <math.h>
#include <bitset>
#include <assert.h>
#define NMax 100010
#define SNMax 400
using namespace std;

const char IN[]="arbore.in",OUT[]="arbore.out";
const int mod= (1<<10);
const int mmod= mod-1;
const int prime=13;


int N,M,psize=350;
int Min[NMax] , Max[NMax] , v[NMax] , s[NMax] , csum[NMax];
bool visit[NMax];
bitset<10*NMax> b[SNMax];
vector<int> ad[NMax];

void Update(int x,int y,int val)
{
    int poz , px , py , i , st ,dr;

    for (poz=1,px=1,py=psize;px<=N;px+=psize,py+=psize,++poz)
    {
        if ( x<=px && py<=y ) csum[poz]+=val;
        else if ( px <= y && px>=x )
        {
            for (i=px;i<=py && i<=N;++i) b[poz][s[i]]=0;
            st=max(x,px);dr=min(py,y);
            for (i=st;i<=dr;++i) s[i]+=val;
            for (i=px;i<=py && i<=N;++i) b[poz][s[i]]=1;
        }
        else if ( x<=py  && py<=y)
        {
            for (i=px;i<=py && i<=N;++i) b[poz][s[i]]=0;
            st=max(x,px);dr=min(py,y);
            for (i=st;i<=dr;++i) s[i]+=val;
            for (i=px;i<=py && i<=N;++i) b[poz][s[i]]=1;
        }
        else if ( px<=x && y<=py )
        {
            for (i=px;i<=py && i<=N;++i) b[poz][s[i]]=0;
            st=x;dr=y;
            for (i=st;i<=dr;++i) s[i]+=val;
            for (i=px;i<=py && i<=N;++i) b[poz][s[i]]=1;
            return;
        }
    }
}

void init()
{
    int poz , px , py , i;

    for (poz=1,px=1,py=psize;px<=N;px+=psize,py+=psize,++poz)
        b[poz][0]=1;
}

int Query(int S)
{

    int poz , px , py , i;

    for (poz=1,px=1,py=psize;px<=N;px+=psize,py+=psize,++poz)
        if ( S-csum[poz]>=0 && b[poz][S-csum[poz]])
        {
            for (i=px;i<=py;++i) if (s[i]+csum[poz]==S) return v[i];
            assert(0);
        }
    return -1;
}

void dfs(int x=1)
{
    int i;
    static int time;
    visit[x]=true;
    Min[x]=++time;v[time]=x;
    for (i=0;i<(int)ad[x].size();++i) if (!visit[ad[x][i]])
        dfs(ad[x][i]);
    Max[x]=time;
}

int main()
{
    int i,c,x,y;
    freopen(IN,"r",stdin);
    scanf("%d%d",&N,&M); //psize= int( sqrt(N) + 0.5 );
    for (i=1;i<N;++i) scanf("%d%d",&x,&y),ad[x].push_back(y),ad[y].push_back(x);
    dfs();

    init();
    freopen(OUT,"w",stdout);
    while (M--)
    {
        scanf("%d",&c);

        switch(c)
        {
            case 1:
            {
                scanf("%d%d",&x,&y);
                Update(Min[x],Max[x],y);
            }
             break;
            case 2:
            {
                scanf("%d",&x);
                printf("%d\n",Query(x));
            }
             break;
        }
    }

    return 0;
}