线段树模板 区间加 区间乘

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_44343213/article/details/102687979

也没啥可说的,就说一下注意事项吧

  1. 注意开long long
  2. 多打优化,加快读,register
  3. 变量名别定义重了
  4. 用宏定义防止代码过长
  5. 如果有取膜,不能忘
  6. 建树记得加,别忘了

模板一:区间加

#include<cstdio>
#define si 100005
#define ll long long
#define re register int
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
using namespace std;
ll n,m,a[si],sum[si*4],tag[si*4];
inline ll read() {
	ll x=0,cf=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-') cf=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=(x<<3)+(x<<1)+ch-'0';
		ch=getchar();
	}
	return x*cf;
}
inline void pushup(ll p) {
	sum[p]=sum[ls(p)]+sum[rs(p)];
}
inline void pushdown(ll p,ll l,ll r) {
	ll mid=(l+r)>>1;
	tag[ls(p)]+=tag[p];
	sum[ls(p)]+=tag[p]*(mid-l+1);
	tag[rs(p)]+=tag[p];
	sum[rs(p)]+=tag[p]*(r-mid);
	tag[p]=0;
}
inline void build(ll p,ll l,ll r) {
	if(l==r) {
		sum[p]=a[l];
		return;
	}
	ll mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	pushup(p);
}
inline void update(ll nl,ll nr,ll l,ll r,ll p,ll k) {
	if(nl<=l&&r<=nr) {
		sum[p]+=k*(r-l+1);
		tag[p]+=k; return;
	}
	pushdown(p,l,r);
	ll mid=(l+r)>>1;
	if(nl<=mid) update(nl,nr,l,mid,ls(p),k);
	if(nr>mid) update(nl,nr,mid+1,r,rs(p),k);
	pushup(p);
}
inline ll query(ll qx,ll qy,ll l,ll r,ll p) {
	ll res=0;
	if(qx<=l&&r<=qy) return sum[p];
	ll mid=(l+r)>>1;
	pushdown(p,l,r);
	if(qx<=mid) res+=query(qx,qy,l,mid,ls(p));
	if(qy>mid) res+=query(qx,qy,mid+1,r,rs(p));
	return res;
}
int main() {
	n=read(),m=read();
	for(re i=1;i<=n;i++) {
		a[i]=read();
	}
	build(1,1,n);
	while(m--) {
		int q=read(),x=read(),y=read();
		if(q==1) {
			int k=read();
			update(x,y,1,n,1,k);
		}
		else printf("%lld\n",query(x,y,1,n,1));
	}
	return 0;
}

模板二:区间乘

#include<cstdio>
#define si 100005
#define ll long long
#define re register ll
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
using namespace std;
struct node {
	ll v,add,mul;
}e[si<<2];
ll n,m,P,a[si];
inline ll read() {
	ll x=0,cf=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-') cf=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=(x<<3)+(x<<1)+ch-'0';
		ch=getchar();
	}
	return x*cf;
}
inline void pushup(ll p) {
	e[p].v=(e[ls(p)].v+e[rs(p)].v)%P;
}
inline void pushdown(ll p,ll l,ll r) {
	ll mid=(l+r)>>1;
	e[ls(p)].v=(e[ls(p)].v*e[p].mul+e[p].add*(mid-l+1))%P;
	e[ls(p)].mul=(e[ls(p)].mul*e[p].mul)%P;
	e[ls(p)].add=(e[ls(p)].add*e[p].mul+e[p].add)%P;
	e[rs(p)].v=(e[rs(p)].v*e[p].mul+e[p].add*(r-mid))%P;
	e[rs(p)].mul=(e[rs(p)].mul*e[p].mul)%P;
	e[rs(p)].add=(e[rs(p)].add*e[p].mul+e[p].add)%P;
	e[p].add=0,e[p].mul=1; return;
}
inline void build(ll p,ll l,ll r) {
	e[p].mul=1;
	if(l==r) {
		e[p].v=a[l];
		return;
	}
	ll mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	pushup(p); return;
}
inline void update1(ll nl,ll nr,ll l,ll r,ll p,ll k) {
	if(nr<l||r<nl) return;
	if(nl<=l&&r<=nr) {
		(e[p].v*=k)%=P;
		(e[p].add*=k)%=P;
		(e[p].mul*=k)%=P;
		return;
	}
	pushdown(p,l,r);
	ll mid=(l+r)>>1;
	if(nl<=mid) update1(nl,nr,l,mid,ls(p),k);
	if(nr>mid) update1(nl,nr,mid+1,r,rs(p),k);
	pushup(p); return;
}
inline void update2(ll nl,ll nr,ll l,ll r,ll p,ll k) {
	if(nr<l||r<nl) return;
	if(nl<=l&&r<=nr) {
		(e[p].add+=k)%=P;
		(e[p].v+=k*(r-l+1))%=P;
		return;
	}
	pushdown(p,l,r);
	ll mid=(l+r)>>1;
	if(nl<=mid) update2(nl,nr,l,mid,ls(p),k);
	if(nr>mid) update2(nl,nr,mid+1,r,rs(p),k);
	pushup(p); return;
}
inline ll query(ll qx,ll qy,ll l,ll r,ll p) {
	ll res=0;
	if(qx<=l&&r<=qy) return e[p].v;
	pushdown(p,l,r);
	ll mid=(l+r)>>1;
	if(qx<=mid) (res+=query(qx,qy,l,mid,ls(p)))%=P;
	if(qy>mid) (res+=query(qx,qy,mid+1,r,rs(p)))%=P;
	return res%P;
}
int main() {
	n=read(),m=read(),P=read();
	for(re i=1;i<=n;i++) {
		a[i]=read();
	}
	build(1,1,n);
	while(m--) {
		ll q=read(),x=read(),y=read();
		if(q==1) {
			ll k=read();
			update1(x,y,1,n,1,k);
		}
		else if(q==2) {
			ll k=read();
			update2(x,y,1,n,1,k);
		}
		else printf("%lld\n",query(x,y,1,n,1));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44343213/article/details/102687979