Pagini recente » Cod sursa (job #1546189) | Cod sursa (job #542495) | Cod sursa (job #2053546) | Cod sursa (job #991648) | Cod sursa (job #931146)
Cod sursa(job #931146)
#include <fstream>
#include <vector>
#include <cstdio>
#include <bitset>
#define SQ 330
#define VM 1000010
#define NM 100010
using namespace std;
FILE* fin=fopen("arbore.in","r");
FILE* fout=fopen("arbore.out","w");
const int maxb=1000000;
char buf[maxb];
int ptr=0;
inline int GetInt()
{
int nr=0;
while(buf[ptr]<'0'||'9'<buf[ptr])
if (++ptr>=maxb) fread(buf,1,maxb,fin),ptr=0;
while ('0'<=buf[ptr]&&buf[ptr]<='9')
{
nr=nr*10+buf[ptr]-'0';
if (++ptr>=maxb) fread(buf,1,maxb,fin),ptr=0;
}
return nr;
}
int N, M, K;
int First[NM], Last[NM];
int Inverse[NM];
vector<int> G[NM];
int V[NM], ListVal[SQ];
int NoLists, SizeS;
int Left[SQ], Right[SQ];
bitset<VM> ListSums[SQ];
int Poz[VM];
void Read ()
{
N=GetInt();
M=GetInt();
for (int i=1; i<N; i++)
{
int a=GetInt(), b=GetInt();
G[a].push_back(b);
G[b].push_back(a);
}
}
void DF (int Node)
{
First[Node]=++K;
Inverse[K]=Node;
for (vector<int>::iterator it=G[Node].begin(); it!=G[Node].end(); ++it)
if (First[*it]==0)
DF(*it);
Last[Node]=K;
}
void BuildLists()
{
for (SizeS=1; SizeS*SizeS<=N; ++SizeS);
--SizeS;
for (int i=1; i<=N;)
{
++NoLists;
Left[NoLists]=i;
Right[NoLists]=min(i+SizeS-1, N);
ListSums[NoLists][0]=1;
i+=SizeS;
}
}
int SearchLeft (int X)
{
int P=1, U=NoLists, M, ANS=1;
while (P<=U)
{
M=(P+U)/2;
if (Left[M]<=X)
{
ANS=M;
P=M+1;
}
else
U=M-1;
}
return ANS;
}
int SearchRight (int X)
{
int P=1, U=NoLists, M, ANS=1;
while (P<=U)
{
M=(P+U)/2;
if (Right[M]>=X)
{
ANS=M;
U=M-1;
}
else
P=M+1;
}
return ANS;
}
inline void Update (int L, int R, int S)
{
int Llim=SearchLeft(L);
int Rlim=SearchRight(R);
for (int i=Llim; i<=Rlim; i++)
{
if (L<=Left[i] && Right[i]<=R)
{
ListVal[i]+=S;
continue;
}
for (int j=Left[i]; j<=Right[i]; j++)
{
ListSums[i][V[j]]=0;
if (Poz[V[j]]==i) Poz[V[j]]=i;
V[j]+=ListVal[i] + (L<=j && j<=R?S:0);
}
ListVal[i]=0;
for (int j=Left[i]; j<=Right[i]; j++)
{
Poz[V[j]]=i;
ListSums[i][V[j]]=1;
}
}
}
inline int Query (int S)
{
int i=Poz[S];
if (i!=0 && ListSums[i][S-ListVal[i]]==1)
{
S-=ListVal[i];
for (int j=Left[i]; j<=Right[i]; j++)
if (V[j]==S)
return Inverse[j];
}
for (i=1; i<=NoLists; i++)
{
if (S<ListVal[i])
continue;
if (ListSums[i][S-ListVal[i]]==1)
{
S-=ListVal[i];
for (int j=Left[i]; j<=Right[i]; j++)
if (V[j]==S)
return Inverse[j];
}
}
return -1;
}
void Solve ()
{
for (int i=1; i<=M; i++)
{
int t=GetInt();
if (t==1)
{
int p=GetInt();
int s=GetInt();
Update(First[p], Last[p], s);
}
else
{
int s=GetInt();
fprintf(fout, "%d\n", Query(s));
}
}
}
int main ()
{
Read();
DF(1);
BuildLists();
Solve();
fclose(fin);
fclose(fout);
return 0;
}