Cod sursa(job #611282)

Utilizator crushackPopescu Silviu crushack Data 31 august 2011 17:06:26
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <stdio.h>
#include <vector>
#include <math.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;

struct hentry{
    int poz,val;
};

int N,M,psize;
int Min[NMax] , Max[NMax] , v[NMax] , s[NMax] , csum[NMax];
bool visit[NMax];
vector<int> ad[NMax];
vector<hentry> H[SNMax][mod];

inline int key(int x){
    return (x*prime)&mmod;
}

void HUpdate(int poz,int x,int val)
{
    int k=key(val);
    hentry e; e.poz=x; e.val=val ;
    H[poz][k].push_back(e);
}

int HQuery(int poz,int val)
{
    int k=key(val),i;
    for (i=0;i<(int)H[poz][k].size();++i) if (H[poz][k][i].val==val)
        return H[poz][k][i].poz;
    return 0;
}

void Hdelete(int poz,int x,int val)
{
    int k=key(val),i,j;
    for (i=j=0;i<(int)H[poz][k].size();++i) if (H[poz][k][i].val!=val || H[poz][k][i].poz!=x)
        H[poz][k][j++]=H[poz][k][i];
    H[poz][k].resize(j);
}

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

    for (poz=1,px=1,py=psize;px<=N;px+=psize,py+=psize,++poz)
        if ( x<=px && py<=y ) csum[poz]+=val;
        else if ( y>=px )
            for ( i=x;i<=py;++i) Hdelete(poz,i,s[i]),s[i]+=val,HUpdate(poz,i,s[i]);
        else
            for (i=px;i<=y;++i) Hdelete(poz,i,s[i]),s[i]+=val,HUpdate(poz,i,s[i]);
}

int Query(int S)
{
    int  px , py , poz;

    for (poz=1,px=1,py=psize;px<=N;px+=psize,py+=psize,++poz)
    {
        int r= HQuery(poz,S-csum[poz]);
        if (r) return r;
    }
    return -1;
}

void init()
{
    int  px , py , poz ,i;
    for (poz=1,px=1,py=psize;px<=N;px+=psize,py+=psize,++poz)
        for (i=px;i<=py;++i) HUpdate(poz,i,s[i]);
}

void dfs(int x=1)
{
    int i;
    static int time;
    visit[x]=true;
    Min[x]=++time;
    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;
}