1.封装好的结构体如下:
template<typename T>
struct DynamicSegtree {
struct node {
T data, tag;
node *lc, *rc;
node(T data_ = 0) : data(data_), tag(0), lc(nullptr), rc(nullptr) {}
void up() {
data = 0;
if(lc != nullptr) data += lc -> data;
if(rc != nullptr) data += rc -> data;
return ;
}
void down(int l, int r) {
if(lc == nullptr) lc = new node;
if(rc == nullptr) rc = new node;
int mid = l + r >> 1;
lc -> data += (mid - l + 1) * tag;
lc -> tag += tag;
rc -> data += (r - mid) * tag;
rc -> tag += tag;
tag = 0;
}
}*rt = new node(0);
void modify(node* rt, int L, int R, int l, int r, T val) {
if(l <= L && R <= r) {
rt -> data += (R - L + 1) * val;
rt -> tag += val;
return ;
}
rt -> down(L, R);
int mid = L + R >> 1;
if(l <= mid) modify(rt -> lc, L, mid, l, r, val);
if(r > mid) modify(rt -> rc, mid+1, R, l, r, val);
rt -> up();
return ;
}
T query(node* rt, int L, int R, int l, int r) {
if(l <= L && R <= r) {
return rt -> data;
}
rt -> down(L, R);
int mid = L + R >> 1;
T ret{};
if(l <= mid) ret += query(rt -> lc, L, mid, l, r);
if(r > mid) ret += query(rt -> rc, mid+1, R, l, r);
return ret;
}
};
//DynamicSegtree<ll> t;
2.板子+使用方法如下:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define ll long long
const int N = 1e6+5, mod = 998244353;
int n,k,tot;
vector<int> a[N];
int ans = 0;
template<typename T>
struct DynamicSegtree {
struct node {
T data, tag;
node *lc, *rc;
node(T data_ = 0) : data(data_), tag(0), lc(nullptr), rc(nullptr) {}
void up() {
data = 0;
if(lc != nullptr) data += lc -> data;
if(rc != nullptr) data += rc -> data;
return ;
}
void down(int l, int r) {
if(lc == nullptr) lc = new node;
if(rc == nullptr) rc = new node;
int mid = l + r >> 1;
lc -> data += (mid - l + 1) * tag;
lc -> tag += tag;
rc -> data += (r - mid) * tag;
rc -> tag += tag;
tag = 0;
}
}*rt = new node(0);
void modify(node* rt, int L, int R, int l, int r, T val) {
if(l <= L && R <= r) {
rt -> data += (R - L + 1) * val;
rt -> tag += val;
return ;
}
rt -> down(L, R);
int mid = L + R >> 1;
if(l <= mid) modify(rt -> lc, L, mid, l, r, val);
if(r > mid) modify(rt -> rc, mid+1, R, l, r, val);
rt -> up();
return ;
}
T query(node* rt, int L, int R, int l, int r) {
if(l <= L && R <= r) {
return rt -> data;
}
rt -> down(L, R);
int mid = L + R >> 1;
T ret{};
if(l <= mid) ret += query(rt -> lc, L, mid, l, r);
if(r > mid) ret += query(rt -> rc, mid+1, R, l, r);
return ret;
}
};
//下面是使用方法介绍
DynamicSegtree<ll> t; //这里建立一个用ll存储的动态开点线段树
const int MAXA = 1e6+5; //最大值域是1e6+5
void solve(){
int m; cin>>m; //假设有m次操作(修改/询问)
while(m--){
int op,l,r,x; cin>>op;
if(op==1){ //1.修改,[l,r]部分加上x
cin>>l>>r>>x;
t.modify(t.rt,1,MAXA,l,r,x);
}else if(op==2){ //2.询问,输出[l,r]部分的和
cin>>l>>r;
cout<<t.query(t.rt,1,MAXA,l,r);
}
}
}
signed main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T=1;
while(T--) solve();
}