区间修改(change to),区间求最小值
//此板子适合修改值为正数时使用,否则需要修改初始化的tr[i].tag;
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1000010;
int t;
int n,m,q;
struct segtree{
int l,r;//这个节点的范围
int val;
int tag;
}tr[maxn*4];
void build(int root,int l,int r)//根节点为1,范围从1-n
{
tr[root].l=l;
tr[root].r=r;
tr[root].tag=-1;//修改值若为负数则要修改,tag的值应在修改范围之外
if(l==r)
{
tr[root].val=INT_MAX;//初始值
return;
}
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
tr[root].val=min(tr[root*2].val,tr[root*2+1].val);
}
void spread(int p)
{
if(tr[p].tag!=-1)
{
tr[p*2].val=tr[p].tag;
tr[p*2+1].val=tr[p].tag;
tr[p*2].tag=tr[p].tag;
tr[p*2+1].tag=tr[p].tag;
tr[p].tag=-1;
}
}
void update(int root,int l,int r,int x)
{
if(l<=tr[root].l&&r>=tr[root].r)
{
tr[root].val=x;
tr[root].tag=x;
return;
}
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
if(l<=mid)
update(root*2,l,r,x);
if(r>mid)
update(root*2+1,l,r,x);
tr[root].val=min(tr[root*2].val,tr[root*2+1].val);
}
int getmin(int root,int l,int r)//单点更新下的
{
if(l<=tr[root].l&&r>=tr[root].r)
return tr[root].val;
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
int ans=INT_MAX;
if(l<=mid)
ans=min(ans,getmin(root*2,l,r));
if(r>mid)
ans=min(ans,getmin(root*2+1,l,r));
return ans;
}
区间修改(change to),区间求和
#include<bits/stdc++.h>
#define int long long //防止爆int
int t;
int n,m,q;
int a[maxn];
struct segtree{
int l,r;
int val;
int tag;
}tr[maxn*4];
void build(int root,int l,int r)
{
tr[root].l=l;
tr[root].r=r;
tr[root].tag=inf;//tag初始化为最大值
if(l==r)
{
tr[root].val=a[l];//初始值
return;
}
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
tr[root].val=tr[root*2].val+tr[root*2+1].val;//统计区间和
}
void spread(int p)
{
if(tr[p].tag!=inf)
{
tr[p*2].val=tr[p].tag*(tr[p*2].r-tr[p*2].l+1);
tr[p*2+1].val=tr[p].tag*(tr[p*2+1].r-tr[p*2+1].l+1);
tr[p*2].tag=tr[p].tag;
tr[p*2+1].tag=tr[p].tag;
tr[p].tag=inf;
}
}
void update(int root,int l,int r,int x)
{
if(l<=tr[root].l&&r>=tr[root].r)
{
tr[root].val=x*(tr[root].r-tr[root].l+1);
tr[root].tag=x;
return;
}
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
if(l<=mid)
update(root*2,l,r,x);
if(r>mid)
update(root*2+1,l,r,x);
tr[root].val=tr[root*2].val+tr[root*2+1].val;
}
int getsum(int root,int l,int r)//单点更新下的
{
if(l<=tr[root].l&&r>=tr[root].r)
return tr[root].val;
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
int ans=0;
if(l<=mid)
ans+=getsum(root*2,l,r);
if(r>mid)
ans+=getsum(root*2+1,l,r);
return ans;
}
最常用,区间加减,区间查询(sum)
#include<bits/stdc++.h>
#define int long long //防止爆int
int t;
int n,m,q;
int a[maxn];
struct segtree{
int l,r;
int val;
int tag;
}tr[maxn*4];
void build(int root,int l,int r)
{
tr[root].l=l;
tr[root].r=r;
tr[root].tag=0;//tag为0则不用修改
if(l==r)
{
tr[root].val=a[l];//初始值
return;
}
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
tr[root].val=tr[root*2].val+tr[root*2+1].val;//统计区间和
}
void spread(int p)
{
if(tr[p].tag!=0)
{
tr[p*2].val+=tr[p].tag*(tr[p*2].r-tr[p*2].l+1);
tr[p*2+1].val+=tr[p].tag*(tr[p*2+1].r-tr[p*2+1].l+1);
tr[p*2].tag+=tr[p].tag;
tr[p*2+1].tag+=tr[p].tag;
tr[p].tag=0;
}
}
void update(int root,int l,int r,int x)
{
if(l<=tr[root].l&&r>=tr[root].r)
{
tr[root].val+=x*(tr[root].r-tr[root].l+1);
tr[root].tag+=x;
return;
}
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
if(l<=mid)
update(root*2,l,r,x);
if(r>mid)
update(root*2+1,l,r,x);
tr[root].val=tr[root*2].val+tr[root*2+1].val;
}
int getsum(int root,int l,int r)//单点更新下的
{
if(l<=tr[root].l&&r>=tr[root].r)
return tr[root].val;
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
int ans=0;
if(l<=mid)
ans+=getsum(root*2,l,r);
if(r>mid)
ans+=getsum(root*2+1,l,r);
return ans;
}
区间加减,区间最值查询(min)
#include<bits/stdc++.h>
#define int long long //防止爆int
using namespace std;
const int maxn=1000010;
const int inf=0x3f3f3f3f;
int t;
int n,m,q;
struct segtree{
int l,r;
int val;
int tag;
}tr[maxn*4];
void build(int root,int l,int r)
{
tr[root].l=l;
tr[root].r=r;
tr[root].tag=0;//tag为0则不用修改
if(l==r)
{
tr[root].val=0;//初始值
return;
}
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
tr[root].val = min(tr[root * 2].val, tr[root * 2 + 1].val);
}
void spread(int p)
{
if(tr[p].tag!=0)
{
tr[p * 2].val += tr[p].tag;
tr[p * 2 + 1].val += tr[p].tag;
tr[p * 2].tag += tr[p].tag;
tr[p * 2 + 1].tag += tr[p].tag;
tr[p].tag = 0;
}
}
void update(int root,int l,int r,int x)
{
if(l<=tr[root].l&&r>=tr[root].r)
{
tr[root].val+=x;
tr[root].tag+=x;
return;
}
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
if(l<=mid)
update(root*2,l,r,x);
if(r>mid)
update(root*2+1,l,r,x);
tr[root].val=min(tr[root*2].val,tr[root*2+1].val);
}
int getsum(int root,int l,int r)//单点更新下的
{
if(l<=tr[root].l&&r>=tr[root].r)
return tr[root].val;
spread(root);
int mid=(tr[root].l+tr[root].r)>>1;
int ans=inf;
if(l<=mid)
ans=min(ans,getsum(root*2,l,r));
if(r>mid)
ans=min(ans,getsum(root*2+1,l,r));
return ans;
}