Pagini recente » Cod sursa (job #328980) | Cod sursa (job #1829424) | Cod sursa (job #1907377) | Cod sursa (job #1637562) | Cod sursa (job #1556741)
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define Nmax 100000
#define sqrtNmax 317
int N,M,id = 0,sqn,B;
vector<int> G[Nmax+1];
int start[Nmax+1],finish[Nmax+1],p[Nmax+1];
bool seen[Nmax+1],have[sqrtNmax+1][1000001];
int Add[sqrtNmax+1], A[Nmax+1];
inline int block(int pos)
{
if (pos % sqn == 0) return pos / sqn;
else return pos / sqn + 1;
}
void dfs(int node)
{
seen[node] = 1;
start[node] = ++id;
p[id] = node;
for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); ++it)
if (!seen[*it])
dfs(*it);
finish[node] = id;
}
void updateBlock(int b)
{
for (int i = (b-1)*sqn+1; i <= min(b*sqn,N); i++)
have[b][A[i]] = 1;
}
void Update(int node,int sum)
{
int block1 = block(start[node]), block2 = block(finish[node]), i;
for (i = start[node]; block(i) == block1 && i <= finish[node]; ++i)
A[i] += sum, have[block1][A[i]-sum] = 0;
updateBlock(block1);
for (block1 = block1 + 1; block1 < block2; ++block1)
Add[block1] += sum;
if (block(start[node]) == block2) return;
for (i = (block2 - 1) * sqn + 1; i <= finish[node]; i++)
A[i] += sum, have[block2][A[i]-sum] = 0;
updateBlock(block2);
}
int getNode(int b,int sum)
{
for (int i = (b-1)*sqn+1; i <= min(b*sqn,N); i++)
if (A[i] == sum) return p[i];
return 0;
}
int Query(int sum)
{
for (int b = 1; b <= B; b++)
if (have[b][sum - Add[b]] && sum-Add[b] >= 0) return getNode(b,sum-Add[b]);
return -1;
}
int main()
{
ifstream fin("arbore.in");
ofstream fout("arbore.out");
fin >> N >> M;
int a,b;
for (int i = 1; i < N; i++)
{
fin >> a >> b;
G[a].push_back(b);
G[b].push_back(a);
}
dfs(1);
sqn = (int)sqrt((double)N);
B = N / sqn;
if (N % sqn != 0) ++B;
for (int i = 0; i <= B; i++)
have[i][0] = 1;
int x,y,z;
for (int i = 1; i <= M; i++)
{
fin >> x;
if (x == 1)
{
fin >> y >> z;
Update(y,z);
}
else
{
fin >> z;
fout << Query(z) << "\n";
}
}
}