Pagini recente » Cod sursa (job #85468) | Cod sursa (job #2002088) | Cod sursa (job #1585989) | Cod sursa (job #1931574) | Cod sursa (job #1959931)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100010, SQMAX = 450;
int N, M;
int bucketSize, bucketNum;
int pos, linear[2 * NMAX];
int first[NMAX], last[NMAX];
int lazy[SQMAX], value[NMAX];
vector<int> G[NMAX];
unordered_map<int, int> freq[SQMAX];
void DFS(int node, int father) {
linear[pos] = node;
first[node] = pos++;
for (int it: G[node])
if (it != father)
DFS(it, node);
linear[pos] = node;
last[node] = pos++;
}
int main() {
assert(freopen("arbore.in", "r", stdin));
assert(freopen("arbore.out", "w", stdout));
int i, j;
scanf("%d %d", &N, &M);
bucketSize = sqrt(N * 2);
bucketNum = N * 2 / bucketSize;
for (i = 0; i < N - 1; ++i) {
int x, y;
scanf("%d %d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
DFS(1, 0);
int currBucket = 0, currRemainder = 0;
for (i = 0; i < 2 * N; ++i) {
++freq[currBucket][0];
++currRemainder;
if (currRemainder == bucketSize) {
++currBucket;
currRemainder = 0;
}
}
while (M--) {
int type, x, y;
scanf("%d", &type);
if (type == 1) {
scanf("%d %d", &x, &y);
int left = first[x], right = last[x];
int leftBucket = left / bucketSize;
int leftBucketPos = left % bucketSize;
int rightBucket = right / bucketSize;
int rightBucketPos = right % bucketSize;
if (leftBucket == rightBucket) {
for (i = leftBucketPos; i <= rightBucketPos; ++i) {
--freq[leftBucket][value[leftBucket * bucketSize + i]];
value[leftBucket * bucketSize + i] += y;
++freq[leftBucket][value[leftBucket * bucketSize + i]];
}
continue;
}
for (i = leftBucket + 1; i <= rightBucket - 1; ++i)
lazy[i] += y;
for (i = leftBucketPos; i < bucketSize; ++i) {
--freq[leftBucket][value[leftBucket * bucketSize + i]];
value[leftBucket * bucketSize + i] += y;
++freq[leftBucket][value[leftBucket * bucketSize + i]];
}
for (i = 0; i <= rightBucketPos; ++i) {
--freq[rightBucket][value[rightBucket * bucketSize + i]];
value[rightBucket * bucketSize + i] += y;
++freq[rightBucket][value[rightBucket * bucketSize + i]];
}
} else {
scanf("%d", &x);
for (i = 0; i <= bucketNum; ++i) {
if (freq[i].count(x - lazy[i])) {
int seek = x - lazy[i];
for (j = 0; j < bucketSize && i * bucketSize + j <= 2 * N; ++j) {
if (value[i * bucketSize + j] == seek) {
cout << linear[i * bucketSize + j] << '\n';
goto Done;
}
}
}
}
cout << "-1\n";
Done:;
}
}
return 0;
}