树剖MLE求调qwq
查看原帖
树剖MLE求调qwq
742017
zhangxiao666楼主2024/1/20 20:38
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int n, m, cnt;
int a[N], now[N];
int head[N], nxt[N], to[N];
int fa[N], dep[N], son[N], siz[N], top[N], id[N];
int tr[N * 4], add[N * 4];

void add_edge(int x, int y)
{
    cnt++;
    nxt[cnt] = head[x];
    to[cnt] = y;
    head[x] = cnt;
}

void dfs1(int x, int f)
{
    fa[x] = f;
    dep[x] = dep[f] + 1;
    siz[x] = 1;
    for(int i = head[x]; i; i = nxt[i])
    {
        if(to[i] == f) continue;
        dfs1(to[i], x);
        siz[x] += siz[to[i]];
        if(siz[son[x]] < siz[to[i]]) son[x] = to[i];
    }
}

void dfs2(int x, int tp)
{
    id[x] = ++cnt;
    now[cnt] = a[x];
    top[x] = tp;
    if(!son[x]) return;
    dfs2(son[x], tp);
    for(int i = head[x]; i; i = nxt[i])
    {
        if(id[to[i]]) continue;
        dfs2(to[i], to[i]);
    }
}

void pushup(int x)
{
    tr[x] = tr[x << 1] + tr[x << 1 | 1];
}

void build(int x, int l, int r)
{
    if(l == r) {tr[x] = now[l]; return;}
    int mid = l + r >> 1;
    build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r);
    pushup(x);
}

void change(int x, int l, int r, int sum)
{
    tr[x] += (r - l + 1) * sum;
    add[x] += sum;
}

void pushdown(int x, int l, int r)
{
    int mid = l + r >> 1;
    change(x << 1, l, mid, add[x]);
    change(x << 1 | 1, mid + 1, r, add[x]);
    add[x] = 0;
}

void update(int x, int l, int r, int ql, int qr, int k)
{
    if(ql <= l && r <= qr) {change(x, l, r, k); return;}
    int mid = l + r >> 1;
    pushdown(x, l, r);
    if(ql <= mid) update(x << 1, l, mid, ql, qr, k);
    if(qr > mid) update(x << 1 | 1, mid + 1, r, ql, qr, k);
    pushup(x);
}

int query(int x, int l, int r, int ql, int qr)
{
    if(ql <= l && r <= qr) return tr[x];
    int mid = l + r >> 1, ans = 0;
    pushdown(x, l, r);
    if(ql <= mid) ans += query(x << 1, l, mid, ql, qr);
    if(qr > mid) ans += query(x << 1 | 1, mid + 1, r, ql, qr);
    return ans;
}

void update_point(int x, int k)
{
    update(1, 1, n, id[x], id[x], k);
}

void update_son(int x, int k)
{
    update(1, 1, n, id[x], id[x] + siz[x] - 1, k);
}

int query_tree(int x, int y)
{
    int ans = 0;
    while(top[x] != top[y])
    {
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        ans += query(1, 1, n, id[top[x]], id[x]);
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    ans += query(1, 1, n, id[x], id[y]);
    return ans;
}

signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        add_edge(x, y), add_edge(y, x);
    }
    cnt = 0;
    dfs1(1, 0);
    dfs2(1, 1);
    build(1, 1, n);
    while(m--)
    {
        int op;
        cin >> op;
        if(op == 1)
        {
            int x, k;
            cin >> x >> k;
            update_point(x, k);
        }
        if(op == 2)
        {
            int x, k;
            cin >> x >> k;
            update_son(x, k);
        }
        if(op == 3)
        {
            int x;
            cin >> x;
            cout << query_tree(x, 1) << "\n";
        }
    }
    return 0;
}
2024/1/20 20:38
加载中...