Pagini recente » Cod sursa (job #2870194) | Cod sursa (job #2679879) | Cod sursa (job #2551861) | Cod sursa (job #1083650) | Cod sursa (job #3304330)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
const int DIM = 1e5;
int n, tt, first[DIM + 3], last[DIM + 3], maxFirst = 0;
vector<int> muchii[DIM + 3];
int euler[2 * DIM + 3], cntEuler = 0;
int blockSize, sumBlock[800], valSolo[2 * DIM + 3];
unordered_map<int, int> sumSolo[800]; ///pt fiecare bloc tin frecventa fiecare valori solo
inline void dfs(int nod, int parent) {
euler[++cntEuler] = nod;
if(first[nod] == 0) first[nod] = cntEuler, maxFirst = max(maxFirst, cntEuler);
last[nod] = cntEuler;
for(int vecin : muchii[nod]) {
if(vecin != parent) {
dfs(vecin, nod);
euler[++cntEuler] = nod;
if(first[nod] == 0) first[nod] = cntEuler, maxFirst = max(maxFirst, cntEuler);
last[nod] = cntEuler;
}
}
}
inline void update(int st, int dr, int val) {
while(st <= dr && st % blockSize != 0) {
if(valSolo[st] > 0) sumSolo[st / blockSize][valSolo[st]]--;
valSolo[st] += val;
sumSolo[st / blockSize][valSolo[st]]++;
st++;
}
while(st + blockSize <= dr) {
sumBlock[st / blockSize] += val;
st += blockSize;
}
while(st <= dr) {
if(valSolo[st] > 0) sumSolo[st / blockSize][valSolo[st]]--;
valSolo[st] += val;
sumSolo[st / blockSize][valSolo[st]]++;
st++;
}
}
inline int query(int st, int dr, int val) {
while(st <= dr && st % blockSize != 0) {
if(sumBlock[st / blockSize] + valSolo[st] == val) return euler[st];
st++;
}
while(st + blockSize <= dr) {
int need = val - sumBlock[st / blockSize];
if(sumSolo[st / blockSize].find(need) != sumSolo[st / blockSize].end() && sumSolo[st / blockSize][need] > 0) {
for(int i=st; i<=st+blockSize; i++)
if(sumBlock[st / blockSize] + valSolo[i] == val) return euler[i];
}
st += blockSize;
}
while(st <= dr) {
if(sumBlock[st / blockSize] + valSolo[st] == val) return euler[st];
st++;
}
return -1;
}
int main()
{
fin >> n >> tt;
for(int i=1; i<n; i++) {
int x, y; fin >> x >> y;
muchii[x].push_back(y);
muchii[y].push_back(x);
}
dfs(1, -1);
for(int i=1; i<=n; i++) last[i] = min(last[i], maxFirst);
blockSize = (int)sqrt(maxFirst);
while(tt--) {
int op; fin >> op;
if(op == 1) {
int poz, val; fin >> poz >> val;
update(first[poz], last[poz], val);
}
else {
int val; fin >> val;
fout << query(1, maxFirst, val) << '\n';
}
//for(int i=1; i<=maxFirst; i++) cout << sumBlock[i / blockSize] + valSolo[i] << " ";
//cout << '\n';
}
return 0;
}