Cod sursa(job #3359431)

Utilizator rares89_Dumitriu Rares rares89_ Data 27 iunie 2026 21:08:39
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("arbore.in");
ofstream fout("arbore.out");

const int NMAX = 100000;

int n, m, timp;
int tin[NMAX + 5], tout[NMAX + 5], euler[NMAX + 5];
int p[NMAX + 5], it[NMAX + 5];
vector<int> g[NMAX + 5];

int mn[4 * NMAX + 5], mx[4 * NMAX + 5], lazy[4 * NMAX + 5], gd[4 * NMAX + 5];

void addnode(int nod, int x) {
    mn[nod] += x;
    mx[nod] += x;
    lazy[nod] += x;
}

void push(int nod) {
    if(!lazy[nod]) {
        return;
    }

    addnode(nod * 2, lazy[nod]);
    addnode(nod * 2 + 1, lazy[nod]);
    lazy[nod] = 0;
}

void pull(int nod) {
    mn[nod] = min(mn[nod * 2], mn[nod * 2 + 1]);
    mx[nod] = max(mx[nod * 2], mx[nod * 2 + 1]);
    gd[nod] = __gcd(gd[nod * 2], gd[nod * 2 + 1]);
    gd[nod] = __gcd(gd[nod], abs(mn[nod * 2] - mn[nod * 2 + 1]));
}

void update(int nod, int l, int r, int a, int b, int x) {
    if(a <= l && r <= b) {
        addnode(nod, x);
        return;
    }

    push(nod);

    int mid = (l + r) / 2;

    if(a <= mid) {
        update(nod * 2, l, mid, a, b, x);
    }

    if(mid < b) {
        update(nod * 2 + 1, mid + 1, r, a, b, x);
    }

    pull(nod);
}

int ok(int nod, int x) {
    if(x < mn[nod] || x > mx[nod]) {
        return 0;
    }

    if(gd[nod] && (x - mn[nod]) % gd[nod]) {
        return 0;
    }

    return 1;
}

int query(int nod, int l, int r, int x) {
    if(!ok(nod, x)) {
        return -1;
    }

    if(mn[nod] == mx[nod]) {
        return euler[l];
    }

    push(nod);

    int mid = (l + r) / 2;
    int ans = query(nod * 2, l, mid, x);

    if(ans != -1) {
        return ans;
    }

    return query(nod * 2 + 1, mid + 1, r, x);
}

int main() {
    fin >> n >> m;

    for(int i = 1; i < n; i++) {
        int a, b;
        fin >> a >> b;

        g[a].push_back(b);
        g[b].push_back(a);
    }

    stack<int> q;
    q.push(1);

    tin[1] = ++timp;
    euler[timp] = 1;

    while(!q.empty()) {
        int nod = q.top();

        if(it[nod] == (int)g[nod].size()) {
            tout[nod] = timp;
            q.pop();
            continue;
        }

        int fiu = g[nod][it[nod]++];

        if(fiu == p[nod]) {
            continue;
        }

        p[fiu] = nod;
        tin[fiu] = ++timp;
        euler[timp] = fiu;
        q.push(fiu);
    }

    while(m--) {
        int tip;
        fin >> tip;

        if(tip == 1) {
            int p, s;
            fin >> p >> s;

            update(1, 1, n, tin[p], tout[p], s);
        } else {
            int s;
            fin >> s;

            fout << query(1, 1, n, s) << "\n";
        }
    }

    return 0;
}