Cod sursa(job #927972)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 26 martie 2013 10:13:04
Problema Arbore Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
#include<fstream>
#include<vector>
using namespace std;
int n,m;
vector <int> G[100100];
bool viz[100100];
int liniarizare[200100],nrl,stg[100100],drt[100100];
struct Interval{int sum,maxim;};
Interval Aint[270000]; //sum=suma primita direct de acel interval,maxim=suma maxima a unui nod din acel interval
int ind,val,op;

inline void Liniarizare(int x)
{
	viz[x]=true;
	liniarizare[++nrl]=x;
	stg[x]=nrl;
	vector <int>::iterator it;
	for(it=G[x].begin();it!=G[x].end();it++)
		if(!viz[*it])
			Liniarizare(*it);
	liniarizare[++nrl]=x;
	drt[x]=nrl;
}

inline void Update(int nod,int st,int dr)
{
	if(stg[ind]<=st && dr<=drt[ind])
		Aint[nod].sum+=val; //intervalul se afla in subarborele lui ind,deci ii dau banii
	else
	{
		int mij=(st+dr)/2;
		if(stg[ind]<=mij)
			Update(2*nod,st,mij);
		if(mij+1<=drt[ind])
			Update(2*nod+1,mij+1,dr);
	}
	//calculez suma maxima de bani a unui nod din intervalul curent
	Aint[nod].maxim=Aint[nod].sum+max(Aint[2*nod].maxim,Aint[2*nod+1].maxim);
}

inline void Query(int nod,int st,int dr,int S)
{
	if(ind>=1) //deja am gasit un nod cu suma ceruta
		return;
	if(Aint[nod].sum==S)
	{
		ind=liniarizare[st]; //acesta este un nod pe care il caut
		return;
	}
	if(st<dr && Aint[nod].sum<S && Aint[nod].maxim>=S)
	{
		//sigur voi gasi intr-un subinterval pe cineva cu suma S-Aint[nod].sum
		int mij=(st+dr)/2;
		Query(2*nod,st,mij,S-Aint[nod].sum);
		Query(2*nod+1,mij+1,dr,S-Aint[nod].sum);
	}
}

int main()
{
	int i,x,y;
	ifstream fin("arbore.in");
	ofstream fout("arbore.out");
	fin>>n>>m;
	for(i=1;i<n;i++)
	{
		fin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	Liniarizare(1);
	for(i=1;i<=m;i++)
	{
		fin>>op;
		if(op==1)
		{
			fin>>ind>>val;
			Update(1,1,nrl);
		}
		else
		{
			fin>>val;
			ind=-1;
			Query(1,1,nrl,val);
			fout<<ind<<"\n";
		}
	}
	fin.close();
	fout.close();
	return 0;
}