Pagini recente » Cod sursa (job #214991) | Cod sursa (job #708806) | Cod sursa (job #615828) | Cod sursa (job #1361997) | Cod sursa (job #927977)
Cod sursa(job #927977)
#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[750000]; //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;
}