先来一个通用的模板
typedef long long ll;
const int maxn = 2e5 + 10;
struct node
{
ll x,minn,maxx,sum,f;
}tree[4 * maxn]; //结构体开4倍空间
ll n,a[maxn],m;
ll x,y,s,op;
void build(int x,int l,int r) //建树 build(1,1,n);
{
if(l == r)
{
tree[x].x = a[l];
tree[x].sum = a[l];
//tree[x].maxx = a[l];
//tree[x].minn = a[l];
return;
}
int mid = (l + r) / 2;
build(x * 2,l,mid);
build(x * 2 + 1,mid + 1,r);
//tree[x].maxx = max(tree[x * 2].maxx,tree[x * 2 + 1].maxx);
//tree[x].minn = max(tree[x * 2].minn,tree[x * 2 + 1].minn);
tree[x].sum = tree[x * 2].sum + tree[x * 2 + 1].sum;
}
void down(int x,int l,int r) //懒惰标记
{
int mid = (l + r) / 2;
tree[x * 2].f += tree[x].f;
tree[x * 2 + 1].f += tree[x].f;
tree[x * 2].sum += tree[x].f * (mid - l + 1);
tree[x * 2 + 1].sum += tree[x].f * (r - mid);
//tree[x * 2].maxx += tree[x].f;
//tree[x * 2 + 1].maxx += tree[x].f;
//tree[x * 2].minn += tree[x].f;
//tree[x * 2 + 1].minn += tree[x].f;
tree[x].f = 0;
}
void add1(int x,int l,int r,int pos,int s) //单点修改 add(1,1,n,x,s)
{
if(l == r)
{
tree[x].x += s;
tree[x].sum += s;
return;
}
if(tree[x].f) down(x,l,r);
int mid = (l + r) / 2;
if(pos <= mid) add1(x * 2,l,mid,pos,s);
else add1(x * 2 + 1,mid + 1,r,pos,s);
//tree[x].maxx = max(tree[x * 2].maxx,tree[x * 2 + 1].maxx);
//tree[x].minn = max(tree[x * 2].minn,tree[x * 2 + 1].minn);
tree[x].sum = tree[x * 2].sum + tree[x * 2 + 1].sum;
}
ll query(int x,int l,int r,int pos) //单点查询 query(1,1,n,x);
{
if(l == r) return tree[x].sum;
if(tree[x].f) down(x,l,r);
int mid = (l + r) / 2;
if(pos <= mid) return query(x * 2,l,mid,pos);
else query(x * 2 + 1,mid + 1,r,pos);
}
void add2(int x,int l,int r,int al,int ar,int s) //区间修改 add2(1,1,n,l,r,s);
{
if(l >= al && r <= ar)
{
tree[x].sum += (r - l + 1) * s; //(r-1)+1区间点的总数
tree[x].f += s;
return;
}
if(tree[x].f) down(x,l,r);
int mid = (l + r) / 2;
if(al <= mid) add2(x * 2,l,mid,al,ar,s);
if(ar > mid) add2(x * 2 + 1,mid + 1,r,al,ar,s);
//tree[x].maxx = max(tree[x * 2].maxx,tree[x * 2 + 1].maxx);
//tree[x].minn = max(tree[x * 2].minn,tree[x * 2 + 1].minn);
tree[x].sum = tree[x * 2].sum + tree[x * 2 + 1].sum;
}
ll query2(int x,int l,int r,int al,int ar)
{
if(l >= al && r <= ar) return tree[x].sum; //或者是maxx/minn
if(tree[x].f) down(x,l,r);
int mid = (l + r) / 2;
if(ar <= mid) return query2(x * 2,l,mid,al,ar);
else if(al > mid) return query2(x * 2 + 1,mid + 1,r,al,ar);
else return query2(x * 2,l,mid,al,ar) + query2(x * 2 + 1,mid + 1,r,al,ar);
}