Pagini recente » Cod sursa (job #1694569) | Cod sursa (job #1217942) | Cod sursa (job #769548) | Cod sursa (job #933286) | Cod sursa (job #1742836)
#include <cstdio>
#include <cstring>
#include <bitset>
#include <ctime>
#include <random>
#define MaxN 100050
#define MaxS 1000050
#define BUCKET 500
#define MaxBuckets 410
#define NIL -1
#define RANDOM_PASS 100
using namespace std;
struct Edge {
int v;
int next;
};
Edge l[2 * (MaxN - 1)];
int adj[MaxN];
int sum[2 * MaxN + BUCKET];
bitset <MaxS + 2> H[MaxBuckets];
int lazy[MaxBuckets];
int euler[2 * MaxN];
pair <int, int> node2Euler[MaxN];
int ptr;
int numBuckets;
static inline void addEdge(const int &u, const int &v, const int &pos) {
l[pos].v =v;
l[pos].next = adj[u];
adj[u] = pos;
}
void DFS(int u, int parent) {
euler[ptr] = u;
node2Euler[u].first = ptr++;
for (int i = adj[u]; i != NIL; i = l[i].next) {
if (l[i].v != parent) {
DFS(l[i].v, u);
}
}
euler[ptr] = u;
node2Euler[u].second = ptr++;
}
static inline int getRandom(void) {
static mt19937 gen(time(0));
int x = gen();
return x < 0 ? -x : x;
}
static inline int randomCheck(const int &need) {
for (int i = 0; i < RANDOM_PASS; i++) {
int bucket = getRandom() % (numBuckets + 1);
if (need - lazy[bucket] >= 0 && H[bucket][need - lazy[bucket]]) {
return bucket;
}
}
return -1;
}
int main() {
freopen("arbore.in", "r", stdin);
freopen("arbore.out", "w", stdout);
int N, Q;
int u, v;
int opType, add;
scanf("%d%d", &N, &Q);
memset(adj, NIL, 4 * N);
for (int i = 1; i < N; i++) {
scanf("%d%d", &u, &v);
addEdge(u - 1, v - 1, 2 * i - 2);
addEdge(v - 1, u - 1, 2 * i - 1);
}
DFS(0, -1);
numBuckets = -1;
for (int i = 0; i < ptr; i++) {
numBuckets += (i == i / BUCKET * BUCKET);
H[numBuckets][0] = 1;
}
while (ptr != ptr / BUCKET * BUCKET) {
sum[ptr++] = MaxS + 1;
}
while (Q--) {
scanf("%d", &opType);
if (opType == 1) {
scanf("%d%d", &u, &add); u--;
int bucket = node2Euler[u].first / BUCKET;
int startBucket = bucket * BUCKET;
int endBucket = startBucket + BUCKET;
for (int i = startBucket; i < endBucket; i++) {
H[bucket][sum[i]] = 0;
}
for (int i = node2Euler[u].first; (i < endBucket) && (i <= node2Euler[u].second); i++) {
sum[i] += add;
}
for (int i = startBucket; i < endBucket; i++) {
H[bucket][sum[i]] = 1;
}
if (node2Euler[u].second / BUCKET != bucket) {
int fnBucket = node2Euler[u].second / BUCKET;
for (int i = bucket + 1; i < fnBucket; i++) {
lazy[i] += add;
}
startBucket = fnBucket * BUCKET;
endBucket = startBucket + BUCKET;
for (int i = startBucket; i < endBucket; i++) {
H[fnBucket][sum[i]] = 0;
}
for (int i = startBucket; i <= node2Euler[u].second; i++) {
sum[i] += add;
}
for (int i = startBucket; i < endBucket; i++) {
H[fnBucket][sum[i]] = 1;
}
}
} else {
scanf("%d", &add);
int bucket = randomCheck(add);
if (bucket == -1) {
do {
bucket++;
} while (bucket <= numBuckets && (add - lazy[bucket] < 0 || !H[bucket][add - lazy[bucket]]));
}
if (bucket <= numBuckets) {
add -= lazy[bucket];
bucket *= BUCKET;
while (sum[bucket] != add) {
bucket++;
}
printf("%d\n", 1 + euler[bucket]);
} else {
puts("-1");
}
}
}
fclose(stdin);
fclose(stdout);
return 0;
}