70分RE求助
查看原帖
70分RE求助
157147
ljh6jz楼主2021/11/5 16:11
#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int N = 2e5 + 5;
ll P;
int n, q, s, times;
int a[N], id[N], o[N], size[N], deep[N], son[N], top[N], f[N];

int num, h[N];

struct edge
{
    int v, next, dis;
} e[N << 1];

ll lazy[N];

inline void insert(int u, int v)
{
    e[++num].v = v;
    e[num].next = h[u];
    h[u] = num;
}

struct tree
{
    int l, r;
    ll a;
} t[N << 2];

inline int read()
{
    int s = 0, f = 0;
    char ch = getchar();
    while (ch < 48 || ch > 57)
    {
        if (ch == '-')
            f = 1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57)
    {
        s = (s << 3) + (s << 1) + (ch ^ 48);
        ch = getchar();
    }
    return f ? -s : s;
}

inline void dfs1(int u, int fa)
{
    f[u] = fa;
    deep[u] = deep[fa] + 1;
    size[u] = 1;
    int maxson = -1;
    for (int i = h[u]; i; i = e[i].next)
    {
        int v = e[i].v;
        if (v == fa)
            continue;
        dfs1(v, u);
        size[u] += size[v];
        if (maxson < size[v])
        {
            maxson = size[v];
            son[u] = v;
        }
    }
}

inline void dfs2(int u, int utop)
{
    id[u] = ++times;
    a[times] = o[u];
    top[u] = utop;
    if (!son[u])
        return;
    dfs2(son[u], utop);
    for (int i = h[u]; i; i = e[i].next)
    {
        int v = e[i].v;
        if (v == f[u] || v == son[u])
            continue;
        dfs2(v, v);
    }
}

inline void pushup(int p)
{
    t[p].a = (t[p << 1].a + t[p << 1 | 1].a) % P;
}

inline void pushdown(int p)
{
    if (lazy[p])
    {
        t[p << 1].a = (t[p << 1].a + (t[p << 1].r - t[p << 1].l + 1) * lazy[p]) % P;
        t[p << 1 | 1].a = (t[p << 1 | 1].a + (t[p << 1 | 1].r - t[p << 1 | 1].l + 1) * lazy[p]) % P;
        lazy[p << 1] = (lazy[p << 1] + lazy[p]) % P;
        lazy[p << 1 | 1] = (lazy[p << 1 | 1] + lazy[p]) % P;
        lazy[p] = 0;
    }
}

inline void build(int p, int l, int r)
{
    t[p].l = l;
    t[p].r = r;
    if (l == r)
    {
        t[p].a = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    pushup(p);
}

inline void update(int p, int x, int y, int k)
{
    if (x <= t[p].l && t[p].r <= y)
    {
        lazy[p] = (lazy[p] + k) % P;
        t[p].a = (t[p].a + (t[p].r - t[p].l + 1) * k) % P;
        return;
    }
    pushdown(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (x <= mid)
    {
        update(p << 1, x, y, k);
    }
    if (y > mid)
    {
        update(p << 1 | 1, x, y, k);
    }
    pushup(p);
}

inline int query(int p, int x, int y)
{
    if (x <= t[p].l && t[p].r <= y)
    {
        return t[p].a;
    }
    pushdown(p);
    int mid = (t[p].l + t[p].r) >> 1, ans = 0;
    if (x <= mid)
    {
        ans = (ans + query(p << 1, x, y)) % P;
    }
    if (y > mid)
    {
        ans = (ans + query(p << 1 | 1, x, y)) % P;
    }
    return ans;
}

inline void update_edge(int x, int y, int k)
{
    while (top[x] != top[y])
    {
        if (deep[top[x]] < deep[top[y]])
            swap(x, y);
        update(1, id[top[x]], id[x], k);
        x = f[top[x]];
    }
    if (deep[x] > deep[y])
        swap(x, y);
    update(1, id[x], id[y], k);
}

inline int query_edge(int x, int y)
{
    ll ans = 0;
    while (top[x] != top[y])
    {
        if (deep[top[x]] < deep[top[y]])
            swap(x, y);
        ans = (ans + query(1, id[top[x]], id[x])) % P;
        x = f[top[x]];
    }
    if (deep[x] > deep[y])
        swap(x, y);
    ans = (ans + query(1, id[x], id[y])) % P;
    return ans;
}

inline void update_tree(int x, int k)
{
    update(1, id[x], id[x] + size[x] - 1, k);
}

inline int query_tree(int x)
{
    return query(1, id[x], id[x] + size[x] - 1);
}

signed main()
{
    freopen("P3384.in", "r", stdin);
//    freopen("P3384.out", "w", stdout);
    n = read(), q = read(), s = read(), P = read();
    for (int i = 1; i <= n; ++i)
    {
        o[i] = read();
    }
    for (int i = 1; i < n; ++i)
    {
        int u = read(), v = read();
        insert(u, v);
        insert(v, u);
    }
    dfs1(s, 0);
    dfs2(s, s);
    build(1, 1, n);
    while (q--)
    {
        int x, y, z, k = read();
        printf("%d %d\n", q, k);
        if (k == 1)
        {
            x = read(), y = read(), z = read();
            update_edge(x, y, z % P);
        }
        else if (k == 2)
        {
            x = read(), y = read();
            printf("%d\n", query_edge(x, y));
        }
        else if (k == 3)
        {
            x = read(), z = read();
            update_tree(x, z % P);
        }
        else
        {
            x = read();
            printf("%d\n", query_tree(x));
        }
    }
    return 0;
}
2021/11/5 16:11
加载中...