蒟蒻代码求调

P3038 [USACO11DEC] Grass Planting G

wanghaolin44243787 @ 2024-08-14 00:27:31

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 100005
char x;
ll n,m,a[MAXN], ans[MAXN << 2], tag[MAXN << 2], id[MAXN], y, z, w, tot[MAXN], fa[MAXN], top[MAXN], dep[MAXN], son[MAXN], cnt = 0, v[MAXN], t;
vector<ll>edge[MAXN];
inline void dfs1(ll now, ll f, ll dp) {
    fa[now] = f;
    dep[now] = dp;
    tot[now] = 1;
    ll maxson = -1;
    for (int i = 0; i < edge[now].size(); i++) {
        if (edge[now][i] == f) {
            continue;
        }
        dfs1(edge[now][i], now, dp + 1);
        tot[now] += tot[edge[now][i]];
        if (maxson < tot[edge[now][i]]) {
            maxson = tot[edge[now][i]];
            son[now] = edge[now][i];
        }
    }
    return;
}
inline void dfs2(ll now, ll topof) {
    id[now] = ++cnt;
    v[cnt] = a[now];
    top[now] = topof;
    if (son[now] == 0)return;
    dfs2(son[now], topof);
    for (int i = 0; i < edge[now].size(); i++) {
        if (edge[now][i] == fa[now] || edge[now][i] == son[now])continue;
        dfs2(edge[now][i], edge[now][i]);
    }
    return;
}
inline void push_down(ll p, ll l, ll r) {
    ll mid = l / 2.0 + r / 2.0;
    ans[p * 2] += tag[p] * (mid - l + 1);
    tag[p * 2] += tag[p];
    ans[p * 2 + 1] += tag[p] * (r - mid);
    tag[p * 2 + 1] += tag[p];
    tag[p] = 0;
}

inline void update(ll dl, ll dr, ll l, ll r, ll p, ll k) {
    if (dl <= l && dr >= r) {
        ans[p] += k * (r - l + 1);
        tag[p] += k;
        return ;
    }
    ll mid = l / 2.0 + r / 2.0;
    push_down(p, l, r);
    if (dl <= mid)update(dl, dr, l, mid, p * 2, k);
    if (dr > mid)update(dl, dr, mid + 1, r, p * 2 + 1, k);
    ans[p] = ans[p * 2] + ans[p * 2 + 1];
    return;
}
ll query(ll dl, ll dr, ll l, ll r, ll p) {
    if (dl <= l && dr >= r)return ans[p];
    ll sum = 0;
    ll mid = l / 2.0 + r / 2.0;
    push_down(p, l, r);
    if (dl <= mid) {
        sum += query(dl, dr, l, mid, p * 2);
    }
    if (dr > mid) {
        sum += query(dl, dr, mid + 1, r, p * 2 + 1);
    }
    return sum;
}
inline void tree_update(ll a, ll b, ll c) {
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        update(id[top[a]], id[a], 1, n, 1, c);
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    update(id[a], id[b], 1, n, 1, c);
    return;
}
ll tree_query(ll a, ll b) {
    ll qq = 0;
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]])swap(a, b);
        qq += query(id[top[a]], id[a], 1, n, 1);
        a = fa[top[a]];
    }
    if (dep[a] > dep[b])swap(a, b);
    qq += query(id[a], id[b], 1, n, 1);
    return qq;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i < n; i++) {
        cin>>y>>z;
        edge[z].push_back(y);
        edge[y].push_back(z);
    }
    dfs1(1, 0, 1);
    dfs2(1, 1);
    for (int i = 1; i <= m; i++) {
        cin >> x>>y>>z;
        if (x == 'P') {
            tree_update(y, z, 1);
        }
        else if (x == 'Q') {
            cout << tree_query(y, z) << "\n";
        }
    }
    return 0;
}

|