Cod sursa(job #445252)

Utilizator indestructiblecont de teste indestructible Data 23 aprilie 2010 11:39:47
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <stdio.h>
#include <vector>
#include <bitset>
#define pb push_back
#define NMAX 100005
#define LMAX 355
#define HMAX 1000005
using namespace std;
int n,m,nr,gr,B[NMAX],C[NMAX],st[NMAX],r;
int D[LMAX],E[NMAX],F[NMAX],G[NMAX];
vector <int> A[NMAX];
bitset <HMAX> marc[LMAX];
char viz[NMAX];
void read()
{
	scanf("%d%d",&n,&m);
	int i,x,y;
	for (i=1; i<n; i++)
	{
		scanf("%d%d",&x,&y);
		A[x].pb(y);
		A[y].pb(x);
	}
}
int cbin(int val)
{
	int i,step=1<<10;
	for (i=0; step; step>>=1)
		if ((i+step)*(i+step)<=n)
			i+=step;
	return i;
}
void dfs(int nod)
{
	int i,vec;
	viz[nod]=1;
	st[++r]=nod;
	B[nod]=r;
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i];
		if (!viz[vec])
			dfs(vec);
	}
	C[nod]=r;
}
void precompute()
{
	nr=cbin(n);
	gr=(n%nr==0) ? n/nr : n/nr+1;
	int i;
	for (i=1; i<gr; i++)
	{
		F[i]=(i-1)*nr+1;
		G[i]=i*nr;
	}
	F[gr]=(gr-1)*nr+1; 
	G[gr]=n;
}
int cb1(int x)
{
	int i,step=(1<<8);
	for (i=0; step; step>>=1)
		if (i+step<=gr && F[i+step]<x)
			i+=step;
	return ++i;
}
int cb2(int x)
{
	int i,step=(1<<8);
	for (i=0; step; step>>=1)
		if (i+step<=gr && G[i+step]<x)
			i+=step;
	return i;
}
int cb3(int x)
{
	int i,step=(1<<8);
	for (i=0; step; step>>=1)
		if (i+step<=gr && F[i+step]<=x)
			i+=step;
	return i;
}
void update(int x,int y,int val)
{
	int st1,st2,p1,p2;
	if (x%nr==1)
		st1=x/nr+1;
	else
		st1=cb1(x);
	if (y%nr==0)
		st2=y/nr;
	else
		st2=cb2(y);
	int i;
	for (i=st1; i<=st2; i++)
		D[i]+=val;
	if (st1<=st2)
	{
		if (x%nr==1)
		{
			if (y%nr==0)
			{
				
			}
			else
			{
				for (i=F[st2+1]; i<=G[st2+1]; i++)
					marc[st2+1][E[i]]=0;
				for (i=F[st2+1]; i<=y; i++)
					E[i]+=val;
				for (i=F[st2+1]; i<=G[st2+1]; i++)
					marc[st2+1][E[i]]=1;
			}
		}
		else
		{
			for (i=F[st1-1]; i<=G[st1-1]; i++)
				marc[st1-1][E[i]]=0;
			for (i=x; i<=G[st1-1]; i++)
				E[i]+=val;
			for (i=F[st1-1]; i<=G[st1-1]; i++)
				marc[st1-1][E[i]]=1;
			if (y%nr==0)
			{
				
			}
			else
			{
				for (i=F[st2+1]; i<=G[st2+1]; i++)
					marc[st2+1][E[i]]=0;
				for (i=F[st2+1]; i<=y; i++)
					E[i]+=val;
				for (i=F[st2+1]; i<=G[st2+1]; i++)
					marc[st2+1][E[i]]=1;
			}
		}
	}
	else
	{
		p1=cb3(x); 
		p2=cb3(y);
		for (i=F[p1]; i<=G[p1]; i++)
			marc[p1][E[i]]=0;
		for (i=x; i<=G[p1] && i<=y; i++)
			E[i]+=val;
		for (i=F[p1]; i<=G[p1]; i++)
			marc[p1][E[i]]=1;
		if (p2>p1)
		{
			for (i=F[p2]; i<=G[p2]; i++)
				marc[p2][E[i]]=0;
			for (i=F[p2]; i<=y; i++)
				E[i]+=val;
			for (i=F[p2]; i<=G[p2]; i++)
				marc[p2][E[i]]=1;
		}
	}
}
int cauta(int x)
{
	int i,j;
	for (i=1; i<=gr; i++)
		if (marc[i][x-D[i]])
		{
			for (j=F[i]; j<=G[i]; j++)
				if (E[j]==x-D[i])
					return st[j];
		}
	return -1;
}
void init()
{
	int i;
	for (i=1; i<=gr; i++)
		marc[i][0]=1;
}
void querys()
{
	int i,tip,x,y;
	for (i=1; i<=m; i++)
	{
		scanf("%d",&tip);
		if (tip==1)
		{
			scanf("%d%d",&x,&y);
			update(B[x],C[x],y);
		}
		else
		{
			scanf("%d",&x);
			printf("%d\n",cauta(x));
		}
	}
}
int main()
{
	freopen("arbore.in","r",stdin);
	freopen("arbore.out","w",stdout);
	read();
	precompute();
	dfs(1);
	init();
	querys();
	return 0;
}