欧拉序 0pts 求调
查看原帖
欧拉序 0pts 求调
516725
cosf楼主2024/3/21 21:33

样例过了,0pts,调了数据发现挂在很灵异的地方。

挂点:给一个点增加了点权之后,和它完全没有子孙关系的点到根的权值和发生了变化,并且变化的差与增加的点权也毫无关系,甚至最大公因数 =1=1。

#include <iostream>
#include <vector>
using namespace std;

#define MAXN 100005

using ll = long long;

struct Tree
{
    int u;
    ll s, t;
} t[MAXN << 4];

vector<int> e[MAXN];

ll val[MAXN];

int st[MAXN], ed[MAXN];
int dfn[MAXN << 1];
int idx = 0;

void dfs(int p, int f)
{
    st[p] = ++idx;
    dfn[idx] = p;
    for (int u : e[p])
    {
        if (u == f)
        {
            continue;
        }
        dfs(u, p);
    }
    ed[p] = ++idx;
    dfn[idx] = -p;
}

int n, m;

void pushup(int p)
{
    t[p] = {
        t[p << 1].u + t[p << 1 | 1].u,
        t[p << 1].s + t[p << 1 | 1].s,
        0};
}

void pushdown(int p)
{
    if (t[p].t)
    {
        t[p << 1].s += t[p << 1].u * t[p].t;
        t[p << 1].t += t[p].t;
        t[p << 1 | 1].s = t[p << 1 | 1].u * t[p].t;
        t[p << 1 | 1].t += t[p].t;
        t[p].t = 0;
    }
}

void build(int p, int l, int r)
{
    if (l == r)
    {
        if (dfn[l] > 0)
        {
            t[p] = {1, val[dfn[l]], 0};
        }
        else
        {
            t[p] = {-1, -val[-dfn[l]], 0};
        }
        return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    pushup(p);
}

void add(int p, int l, int r, int q, ll v)
{
    if (l == r)
    {
        t[p].s += t[p].u * v;
        t[p].t += v;
        return;
    }
    pushdown(p);
    int mid = (l + r) >> 1;
    if (mid >= q)
    {
        add(p << 1, l, mid, q, v);
    }
    else
    {
        add(p << 1 | 1, mid + 1, r, q, v);
    }
    pushup(p);
}

void add(int p, int l, int r, int ql, int qr, ll v)
{
    if (ql <= l && r <= qr)
    {
        t[p].s += t[p].u * v;
        t[p].t += v;
        return;
    }
    pushdown(p);
    int mid = (l + r) >> 1;
    if (mid >= ql)
    {
        add(p << 1, l, mid, ql, qr, v);
    }
    if (mid < qr)
    {
        add(p << 1 | 1, mid + 1, r, ql, qr, v);
    }
    pushup(p);
}

ll query(int p, int l, int r, int q)
{
    if (r <= q)
    {
        return t[p].s;
    }
    pushdown(p);
    int mid = (l + r) >> 1;
    if (mid < q)
    {
        return query(p << 1, l, mid, q) + query(p << 1 | 1, mid + 1, r, q);
    }
    else
    {
        return query(p << 1, l, mid, q);
    }
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> val[i];
    }
    for (int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    dfs(1, 1);
    build(1, 1, 2 * n);
    while (m--)
    {
        int o, x;
        ll a;
        cin >> o >> x;
        if (o == 1)
        {
            cin >> a;
            add(1, 1, 2 * n, st[x], a);
            add(1, 1, 2 * n, ed[x], a);
        }
        if (o == 2)
        {
            cin >> a;
            add(1, 1, 2 * n, st[x], ed[x], a);
        }
        if (o == 3)
        {
            cout << query(1, 1, 2 * n, st[x]) << endl;
        }
    }
    return 0;
}
2024/3/21 21:33
加载中...