Cod sursa(job #993168)

Utilizator raulstoinStoin Raul raulstoin Data 3 septembrie 2013 13:59:41
Problema Arbore Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>

#define NMAX 100002
#define SQRT 320

using namespace std;

FILE *fin,*fout;

vector<int> G[NMAX];
int n,m,lin[NMAX],first[NMAX],last[NMAX],k,node_val[NMAX];

struct piece
{
	bitset<1000002> val;
	int left,right,common;
}v[SQRT];

void read()
{
	fin=fopen("arbore.in","r");
	fout=fopen("arbore.out","w");
	fscanf(fin,"%d %d",&n,&m);
	for(int i=1,x,y;i<n;i++)
	{
		fscanf(fin,"%d %d",&x,&y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
}

void DFS(int nod,int TT)
{
	lin[++k]=nod;
	first[nod]=k;
	for(size_t i=0;i<G[nod].size();i++)
		if(G[nod][i]!=TT)
			DFS(G[nod][i],nod);
	last[nod]=k;
}

void split()
{
	k=0;
	for(int i=1,L=(int)sqrtl(n);i<=n;i+=L)
	{
		v[++k].left=i;
		v[k].right=min(i+L-1,n);
		v[k].val[0]=1;
	}
}

void update(int left,int right,int add)
{
	for(int i=1;i<=k;i++)
	{
		if(v[i].left>right)
			break;
		if(v[i].right<left)
			continue;
		if(left<=v[i].left && v[i].right<=right)
		{
			v[i].common+=add;
			continue;
		}
		v[i].val.reset();
		for(int j=v[i].left;j<=v[i].right;j++)
		{
			node_val[j]+=v[i].common;
			if(left<=j && right>=j)
				node_val[j]+=add;
			v[i].val[node_val[j]]=1;
		}
		v[i].common=0;
	}
}

int query(int sum)
{
	for(int i=1;i<=k;i++)
		if(v[i].common<=sum && v[i].val[sum-v[i].common])
			for(int j=v[i].left;j<=v[i].right;j++)
				if(sum-v[i].common==node_val[j])
					return lin[j];
	return -1;
}

void solve()
{
	DFS(1,0);
	split();
	for(int a,b,c;m;m--)
	{
		fscanf(fin,"%d %d",&a,&b);
		if(a==1)
		{
			fscanf(fin,"%d",&c);
			update(first[b],last[b],c);
			continue;
		}
		fprintf(fout,"%d\n",query(b));
	}
}

int main()
{
	read();
	solve();
	return 0;
}