Cod sursa(job #614744)

Utilizator antoanelaAntoanela Siminiuc antoanela Data 7 octombrie 2011 16:53:11
Problema Arbore Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <cstdio>
#include <vector>
using namespace std;
#define nmax 100010
#define L 31
#define lmax 32000
#define rmax 350

vector <int> g[nmax];
int n, m, h, st[nmax], dr[nmax], u[nmax], c[rmax][lmax], rad, b[rmax], a[nmax], sol, p[nmax];

void dfs(int nod)
{
	st[nod]=++h;
	u[nod]=1;
	int i, v;
	for (i=0; i<g[nod].size(); i++)
	{
		v=g[nod][i];
		if (!u[v]) dfs(v);
	}
	dr[nod]=h;
}

void update_int(int pi, int pf, int ind, int pst, int pdr, int s)
{
	int i, x, y;
	for (i=pi; i<=pf && i<=n; i++)
	{
		x=a[i];
		y=x%L;
		x/=L;
		if ((c[ind][x]>>y)&1) c[ind][x]-=(1<<y);
	}
	for (i=pst; i<=pdr && i<=n; i++) a[i]+=s;
	for (i=pi; i<=pf && i<=n; i++)
	{
		x=a[i];
		y=x%L;
		x/=L;
		if (!((c[ind][x]>>y)&1)) c[ind][x]+=(1<<y);
	}
}

void update(int st, int dr, int s)
{
	int xi, i, x=st/rad, y;
	if (st%rad) x++; 
	y=x*rad;
	if (dr<y) y=dr;
	update_int((x-1)*rad+1, x*rad, x, st, y, s);
	xi=x+1;
	x=dr/rad;
	if (dr%rad) x++; 
	y=(x-1)*rad+1;
	if (st>y) y=st;
	if (x!=xi-1) 
		update_int((x-1)*rad+1, x*rad, x, y, dr, s);
	for (i=xi; i<x; i++) b[i]+=s;
}

void query(int S)
{
	sol=-1;
	int i, s, x, j, y, ok=0;
	for (i=1; i<=rad; i++)
	{
		s=S-b[i];
		if (s>=0)
		{
			x=s/L;
			y=s%L;
			if (c[i][x]&(1<<y)) ok=1;
		}
		if (ok)
			for (j=(i-1)*rad+1; j<=i*rad; j++)
				if (a[j]==s) 
				{
					sol=p[j];
					return;
				}
	}
}

int main()
{
	freopen("arbore.in","r",stdin);
	freopen("arbore.out","w",stdout);
	scanf("%d %d", &n, &m);
	int i, x, y, t, pp, s;
	for (i=1; i<n; i++)
	{
		scanf("%d %d", &x, &y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1);
	for (i=1; i<=n; i++) p[st[i]]=i;
	for (rad=1; rad*rad<n; rad++);
	while (m--)
	{
		scanf("%d", &t);
		if (t==1)
		{
			scanf("%d %d",&pp, &s);
			update(st[pp], dr[pp], s);
		} else
		{
			scanf("%d", &s);
			query(s);
			printf("%d\n",sol);
		}
	}
}