线段树模板合集
区间加一个数,区间求和(带懒标记)
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ull unsigned long long
#define ll long long
#define INF 0x3f3f3f3f
#define N 400010
#define lson rt<<1
#define rson rt<<1|1
#define mo 80112002
#define lowbit(x) (x)&(-(x))
void FRE(){freopen("subsets.in","r",stdin);freopen("subsets.out","w",stdout);}
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ll)(ch-'0');ch=getchar();}
return x*f;
}
ll sum[N],add[N];
int n,Q;
void pushup(int rt)
{
sum[rt]=sum[lson] + sum[rson];
}
void build(int rt , int l ,int r)
{
add[rt] = 0;
if (l == r)
{
sum[rt]=read();
return ;
}
int mid=(l + r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(rt);
return ;
}
void pushdown(int rt,int l,int r)
{
if (add[rt])
{
add[lson]+=add[rt];
add[rson]+=add[rt];
int mid=(l+r)>>1;
sum[lson]+=add[rt]*(mid-l+1);
sum[rson]+=add[rt]*(r-mid);
add[rt]=0;
}
return ;
}
void modify(int rt,int l,int r,int x,int y,int val)
{
if (x<=l && y>=r)
{
add[rt]+=val;
sum[rt]+=val*(r-l+1);
return ;
}
pushdown(rt,l,r);
int mid=(l+r)>>1;
if (x<=mid) modify(lson,l,mid,x,y,val);
if (mid<y) modify(rson,mid+1,r,x,y,val);
pushup(rt);
return ;
}
ll query(int rt , int l , int r ,int x , int y)
{
if (x<=l && r<=y) return sum[rt];
pushdown(rt,l,r);
int mid=(l+r)>>1;
ll res=0;
if (x<=mid) res+=query(lson,l,mid,x,y);
if (mid<y) res+=query(rson, mid+1,r,x,y);
return res;
}
int main()
{
n=read();Q=read();
build(1,1,n);
while (Q--)
{
int ty=read(),x=read(),y=read();
if (ty==1)
{
int k=read();
modify(1,1,n,x,y,k);
}
else
{
printf("%lld\n",query(1,1,n,x,y));
}
}
}
区间开平方
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define inf 1e18
#define ll long long
#define N 1000010
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,m;
ll mx[N],mn[N],sum[N],tag[N];
void pushup(int rt)
{
sum[rt]=sum[lson]+sum[rson];
mx[rt]=max(mx[lson],mx[rson]);
mn[rt]=min(mn[lson],mn[rson]);
}
void pushdown(int rt,int l,int r)
{
if (!tag[rt]) return ;
int mid=(l+r)>>1;
tag[lson]+=tag[rt],tag[rson]+=tag[rt];
sum[lson]+=1LL*(mid-l+1)*tag[rt];
sum[rson]+=1LL*(r-mid)*tag[rt];
mx[lson]+=tag[rt],mx[rson]+=tag[rt];
mn[lson]+=tag[rt],mn[rson]+=tag[rt];
tag[rt]=0;
}
void build(int rt,int l,int r)
{
if (l==r) {mx[rt]=mn[rt]=sum[rt]=read();return ;}
int mid=(l+r)>>1;
build (lson,l,mid),build(rson,mid+1,r);
pushup(rt);
}
bool check(int rt)
{
return (mx[rt]==mn[rt]||(mx[rt]-mn[rt]==floor(sqrt(mx[rt]))-floor(sqrt(mn[rt]))));
}
void modify(int rt,int l,int r,int x,int y)
{
if (x<=l&&r<=y&&check(rt))
{
ll val=floor(sqrt(mx[rt]))-mx[rt];
tag[rt]+=val;sum[rt]+=(r-l+1)*val;
mn[rt]+=val;mx[rt]+=val;
return ;
}
int mid=(l+r)>>1;
if (tag[rt]) pushdown(rt,l,r);
if (x<=mid) modify(lson,l,mid,x,y);
if (y>mid) modify(rson,mid+1,r,x,y);
pushup(rt);
}
ll query(int rt,int l,int r,int x,int y)
{
if (x<=l&&r<=y) return sum[rt];
pushdown(rt,l,r);
int mid=(l+r)>>1;ll res=0;
if (x<=mid) res+=query(lson,l,mid,x,y);
if (y>mid) res+=query(rson,mid+1,r,x,y);
return res;
}
int main()
{
n=read();
build(1,1,n);
int m=read();
while (m--)
{
int ty=read(),x=read(),y=read();
if (x>y) swap(x,y);
if (!ty) modify(1,1,n,x,y);
else printf("%lld\n",query(1,1,n,x,y));
}
return 0;
}
看了下题解,好像大家都打的更简短些,建议直接看题解
区间求max,min:
其实就把第一个的pushup和sum改一下就行。
区间替换:
把区间加减的“+=val”改成“=val”就行。