#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1e18
#define pll pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define fi first
#define se second
#define lll __int128
const int N = 2e5 + 5; //节点上界
ll root[N], idx; //每个版本根节点, 编号器
struct XT {
struct node{ll ln, rn, l, r, sum, add;}tr[N * 22]; //左儿子, 右儿子, 左边界, 右边界, 区间和, 懒标记
void pushup(ll o){
tr[o].sum = tr[tr[o].ln].sum + tr[tr[o].rn].sum;
}
void pushdown(ll o){
if(tr[o].add){
tr[++idx] = tr[tr[o].ln];
tr[o].ln = idx;
tr[++idx] = tr[tr[o].rn];
tr[o].rn = idx;
ll l = tr[o].ln, r = tr[o].rn;
tr[l].sum += tr[o].add * (tr[l].r - tr[l].l + 1);
tr[r].sum += tr[o].add * (tr[r].r - tr[r].l + 1);
tr[l].add += tr[o].add;
tr[r].add += tr[o].add;
tr[o].add = 0;
}
}
void build(ll &o, ll l, ll r){ //创建空树, 一般是0版本
o = ++idx;
tr[o].l = l;
tr[o].r = r;
if(l == r) return;
ll m = (l + r) >> 1;
build(tr[o].ln, l, m);
build(tr[o].rn, m + 1, r);
}
void ins(ll p, ll &o, ll L, ll R, ll add){ //区间加 (前版本p, 当前版本o)
o = ++idx;
tr[o] = tr[p];
ll l = tr[o].l, r = tr[o].r;
if(L <= tr[o].l && R >= tr[o].r){
tr[o].sum += add * (tr[o].r - tr[o].l + 1);
tr[o].add += add;
return;
}
ll m = (l + r) >> 1;
pushdown(p);
pushdown(o);
if(L <= m)
ins(tr[p].ln, tr[o].ln, L, R, add);
if(R > m)
ins(tr[p].rn, tr[o].rn, L, R, add);
pushup(p);
pushup(o);
}
ll query(ll p, ll o, ll L, ll R){ //版本作差查询区间和
ll l = tr[o].l, r = tr[o].r;
if(L <= l && R >= r)
return tr[o].sum - tr[p].sum;
pushdown(p);
pushdown(o);
ll m = (l + r) >> 1, res = 0;
if(L <= m)
res += query(tr[p].ln, tr[o].ln, L, R);
if(R > m)
res += query(tr[p].rn, tr[o].rn, L, R);
pushup(p);
pushup(o);
return res;
}
}xt;
int main() {
return 0;
}
主席树的区间修改
于 2024-01-24 13:10:07 首次发布