线段树板子
耗费了两天$AC$了线段树的两道模板。就把我自己的代码贴出来以后$DEBUG$的时候做个参考吧。
线段树壹
#include <cstdio>
typedef long long ll;
const int N = 100000+10;
int n,m;
ll a[N];
struct Segment_Tree {
#define lson (o<<1)
#define rson (o<<1|1)
ll sumv[N<<2],addv[N<<2];
void pushup(int o) {
sumv[o]=sumv[lson]+sumv[rson];
}
void pushdown(int o,int l,int r) {
if(addv[o]) {
int mid=(l+r)>>1;
sumv[lson]+=addv[o]*(mid-l+1);
sumv[rson]+=addv[o]*(r-mid);
addv[lson]+=addv[o];
addv[rson]+=addv[o];
addv[o]=0;
}
}
void bulid(int o,int l,int r) {
if(l == r) {
sumv[o]=a[l];
return ;
}
addv[o]=0;
int mid=(l+r)>>1;
bulid(lson,l,mid);bulid(rson,mid+1,r);
pushup(o);
}
void change(int o,int l,int r,int q,ll v) {
if(l == r) {
sumv[o]+=v;
}
int mid=(l+r)>>1;
if(q <= mid) {
change(lson,l,mid,q,v);
} else {
change(rson,mid+1,r,q,v);
}
pushup(o);
}
void optadd(int o,int l,int r,int ql,int qr,ll v) {
if(ql<=l && r<=qr) {
addv[o]+=v;sumv[o]+=(r-l+1)*v;
return ;
}
int mid=(l+r)>>1;
pushdown(o,l,r);
if(ql <= mid) {
optadd(lson,l,mid,ql,qr,v);
}
if(qr > mid) {
optadd(rson,mid+1,r,ql,qr,v);
}
pushup(o);
}
ll querysum(int o,int l,int r,int ql,int qr) {
if(ql<=l && r<=qr) {
return sumv[o];
}
int mid=(l+r)>>1;
ll ans=0;
pushdown(o,l,r);
if(ql <= mid) {
ans+=querysum(lson,l,mid,ql,qr);
}
if(qr > mid) {
ans+=querysum(rson,mid+1,r,ql,qr);
}
return ans;
}
};
int main(void) {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) {
scanf("%lld",&a[i]);
}
Segment_Tree T;
T.bulid(1,1,n);
for(int i=1; i<=m; i++) {
int k;
scanf("%d",&k);
if(k == 1) {
ll x,y,v;
scanf("%lld%lld%lld",&x,&y,&v);
T.optadd(1,1,n,x,y,v);
} else {
ll x,y;
scanf("%lld%lld",&x,&y);
printf("%lld\n",T.querysum(1,1,n,x,y));
}
}
return 0;
}
线段树贰
#include <cstdio>
int P;
const int N = 100000+10;
int a[N];
struct Segment_Tree {
#define lson (o<<1)
#define rson (o<<1|1)
#define ll long long
ll sumv[N<<2],addv[N<<2],mulv[N<<2];
ll mul(ll a,ll b) {
return (a*b)%P;
}
ll sum(ll a,ll b) {
return (a+b)%P;
}
void pushup(int o) {
sumv[o]=sum(sumv[lson],sumv[rson]);
}
void pushdown(int o,int l,int r) {
if(!addv[o] && mulv[o] == 1) {
return ;
}
int mid=(l+r)>>1;
sumv[lson]=mul(sumv[lson],mulv[o]);
sumv[rson]=mul(sumv[rson],mulv[o]);
mulv[lson]=mul(mulv[lson],mulv[o]);
mulv[rson]=mul(mulv[rson],mulv[o]);
sumv[lson]=sum(sumv[lson],addv[o]*(mid-l+1));
sumv[rson]=sum(sumv[rson],addv[o]*(r-mid));
addv[lson]=sum(mul(addv[lson],mulv[o]),addv[o]);
addv[rson]=sum(mul(addv[rson],mulv[o]),addv[o]);
addv[o]=0;mulv[o]=1;
}
void bulid(int o,int l,int r) {
mulv[o]=1;
addv[o]=0;
if(l == r) {
sumv[o]=a[l];
return ;
}
int mid=(l+r)>>1;
bulid(lson,l,mid);bulid(rson,mid+1,r);
pushup(o);
}
void optadd1(int o,int l,int r,int ql,int qr,int v) {
if(ql<=l && r<=qr) {
sumv[o]=mul(sumv[o],v);
mulv[o]=mul(mulv[o],v);
addv[o]=mul(addv[o],v);
return ;
}
int mid=(l+r)>>1;
pushdown(o,l,r);
if(ql <= mid) {
optadd1(lson,l,mid,ql,qr,v);
}
if(qr > mid) {
optadd1(rson,mid+1,r,ql,qr,v);
}
pushup(o);
}
void optadd2(int o,int l,int r,int ql,int qr,int v) {
if(ql<=l && r<=qr) {
sumv[o]=sum(sumv[o],mul(v,(r-l+1)));addv[o]=sum(addv[o],v);
return ;
}
int mid=(l+r)>>1;
pushdown(o,l,r);
if(ql <= mid) {
optadd2(lson,l,mid,ql,qr,v);
}
if(qr > mid) {
optadd2(rson,mid+1,r,ql,qr,v);
}
pushup(o);
}
ll querysum(int o,int l,int r,int ql,int qr) {
if(ql<=l && r<=qr) {
return sumv[o];
}
int mid=(l+r)>>1;
ll sum=0;
pushdown(o,l,r);
if(ql <= mid) {
sum+=querysum(lson,l,mid,ql,qr);
}
if(qr > mid) {
sum+=querysum(rson,mid+1,r,ql,qr);
}
return sum;
}
}T;
int main(void) {
int n,m;
scanf("%d%d%d",&n,&m,&P);
for(int i=1; i<=n; i++) {
scanf("%lld",&a[i]);
}
T.bulid(1,1,n);
for(int i=1; i<=m; i++) {
int p;
scanf("%d",&p);
if(p == 3) {
int x,y;
scanf("%d%d",&x,&y);
printf("%lld\n",T.querysum(1,1,n,x,y)%P);
} else {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(p == 1) {
T.optadd1(1,1,n,x,y,z);
} else {
T.optadd2(1,1,n,x,y,z);
}
}
}
return 0;
}