社区讨论

树剖2A5W3M求救,虽然我觉得不会有人回复我qwq

P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 16

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
16 条
当前快照
1 份
快照标识符
@mi7yi4kz
此快照首次捕获于
2025/11/21 05:41
4 个月前
此快照最后确认于
2025/11/21 06:43
4 个月前
查看原帖
CPP
#include <iostream>
#include <cstdio>
#define ll long long
#define MAXN 100005
#define update                                          \
    st[root].v = st[root << 1].v + st[root << 1 | 1].v; \
    if (st[root].v >= mod)                              \
        st[root].v -= mod;
using namespace std;
inline ll read()
{
    ll x = 0, f = 1;
    char c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            f = -1;
    for (; isdigit(c); c = getchar())
        x = (x << 3) + (x << 1) + c - '0';
    return x * f;
}
struct node
{
    ll v, add;
} st[MAXN << 2];
ll n, m, r, mod, w[MAXN], cnt, head[MAXN], to[MAXN], next[MAXN], siz[MAXN], son[MAXN], seg[MAXN], nw[MAXN], deep[MAXN], fa[MAXN], top[MAXN], tot;

inline void addedge(ll u, ll v)
{
    next[++cnt] = head[u];
    to[cnt] = v;
    head[u] = cnt;

    next[++cnt] = head[v];
    to[cnt] = u;
    head[v] = cnt;
}
void dfs1(ll x, ll FA, ll d) //处理son,siz,fa
{
    deep[x] = d;
    fa[x] = FA;
    siz[x] = 1;
    ll maxson = -1;
    for (register ll i = head[x]; i; i = next[i])
    {
        if (to[i] == FA)
            continue;
        dfs1(to[i], x, d + 1);
        siz[x] += siz[to[i]];
        if (siz[to[i]] > maxson)
            son[x] = to[i], maxson = siz[to[i]];
    }
}
void dfs2(ll x, ll TOP) //处理top
{                       //注意处理顺序
    seg[x] = ++tot;     //每个点在线段树中的新编号
    nw[tot] = w[x];     //每个新编号的值
    top[x] = TOP;
    if (!son[x])
        return;
    dfs2(son[x], TOP);
    for (register ll i = head[x]; i; i = next[i])
    {
        if (to[i] == fa[x] || to[i] == son[x])
            continue;
        dfs2(to[i], to[i]);
    }
}
inline void build(ll root, ll l, ll r)
{
    if (l == r)
    {
        st[root].v = nw[l];
        return;
    }
    ll m = (l + r) >> 1;
    build(root << 1, l, m);
    build(root << 1 | 1, m + 1, r);
    update;
    return;
}
inline void pushdown(ll root, ll l, ll r)
{
    ll m = (l + r) >> 1;
    st[root << 1].v = (st[root << 1].v + st[root].add * (m - l + 1) % mod) % mod;
    st[root << 1 | 1].v = (st[root << 1 | 1].v + st[root].add * (r - m) % mod) % mod;
    st[root << 1].add = (st[root << 1].add + st[root].add) % mod;
    st[root << 1 | 1].add = (st[root << 1 | 1].add + st[root].add) % mod;
    st[root].add = 0;
    return;
}
inline void ADD(ll root, ll stdl, ll stdr, ll l, ll r, long long k)
{
    if (r < stdl || stdr < l)
        return;
    if (l <= stdl && stdr <= r)
    {
        st[root].add = (st[root].add + k) % mod;
        st[root].v = (st[root].v + k * (stdr - stdl + 1) % mod) % mod;
        return;
    }
    pushdown(root, stdl, stdr);
    ll m = (stdl + stdr) >> 1;
    ADD(root << 1, stdl, m, l, r, k);
    ADD(root << 1 | 1, m + 1, stdr, l, r, k);
    update;
    return;
}
inline ll query(ll root, ll stdl, ll stdr, ll l, ll r)
{
    if (r < stdl || stdr < l)
        return 0;
    if (l <= stdl && stdr <= r)
        return st[root].v % mod;
    pushdown(root, stdl, stdr);
    ll m = (stdl + stdr) >> 1;
    return (query(root << 1, stdl, m, l, r) + query(root << 1 | 1, m + 1, stdr, l, r)) % mod;
}

回复

16 条回复,欢迎继续交流。

正在加载回复...