线段树模板

区间和

#include<cstdio>
#define ll long long
const int MAXN=100010;
struct Tree {
#define lson (o<<1)
#define rson (o<<1|1)
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
#define add(x) tree[x].add
	ll sum,add;
	int l,r;
} tree[MAXN<<2];
ll a[MAXN];
void build(int o,int l,int r) {
	l(o)=l,r(o)=r;
	add(o)=0;
	if(l==r) {
		sum(o)=a[l];
		return;
	}
	int mid=(l(o)+r(o))>>1;
	if(l<=mid)build(lson,l,mid);
	if(r>mid)build(rson,mid+1,r);
	sum(o)=sum(lson)+sum(rson);
}
void spread(int o) {
	if(add(o)) {
		sum(lson)+=add(o)*(r(lson)-l(lson)+1);
		sum(rson)+=add(o)*(r(rson)-l(rson)+1);
		add(lson)+=add(o);
		add(rson)+=add(o);
		add(o)=0;
	}
}
void change(int o,int l,int r,ll d) {
	if(l<=l(o)&&r(o)<=r) {
		add(o)+=d;
		sum(o)+=d*(r(o)-l(o)+1);
		return;
	}
	spread(o);
	int mid=(l(o)+r(o))>>1;
	if(l<=mid)change(lson,l,r,d);
	if(r>mid)change(rson,l,r,d);
	sum(o)=sum(lson)+sum(rson);
	return;
}
ll ask(int o,int l,int r) {
	if(l<=l(o)&&r(o)<=r)return sum(o);
	spread(o);
	int mid=(l(o)+r(o))>>1;
	ll val=0;
	if(l<=mid)val+=ask(lson,l,r);
	if(r>mid)val+=ask(rson,l,r);
	return val;
}
inline ll read(){
	char ch=getchar(),f=1;
	ll x=0;
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return f*x;
}
inline void write(ll x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
inline void wrln(ll x){
	write(x);
	putchar('\n');
}
int main() {
	int n,m;
	n=read();m=read();
	for(int i=1; i<=n; i++)scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=1; i<=m; i++) {
		ll op,x,y,k;
		op=read();x=read();y=read();
		if(op==1) {
			k=read();
			change(1,x,y,k);
		} else wrln(ask(1,x,y));
	}
	return 0;
}

区间积与和
#include<cstdio>
const int N=100100;
#define LL long long
LL p;
struct Tree{
	int l,r;
	LL sum,add,mul;
	#define sum(x) tree[x].sum
	#define add(x) tree[x].add
	#define mul(x) tree[x].mul
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define lch (o<<1)
	#define rch (o<<1|1)
}tree[N<<2];
int a[N];
void build(int o,int l,int r){
	add(o)=sum(o)=0,mul(o)=1,l(o)=l,r(o)=r;
	if(l==r){
		sum(o)=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	if(l<=mid)build(lch,l,mid);
	if(r>mid)build(rch,mid+1,r);
	sum(o)=(sum(lch)+sum(rch))%p;
}
void spread(int o){
	sum(lch)=(sum(lch)*mul(o)+add(o)*(r(lch)-l(lch)+1))%p;
	sum(rch)=(sum(rch)*mul(o)+add(o)*(r(rch)-l(rch)+1))%p;
	add(lch)=(add(lch)*mul(o)+add(o))%p;
	add(rch)=(add(rch)*mul(o)+add(o))%p;
	mul(lch)=(mul(lch)*mul(o))%p;
	mul(rch)=(mul(rch)*mul(o))%p;
	add(o)=0;
	mul(o)=1;
}
void change(int o,int l,int r,LL add,LL mul){
	if(l<=l(o)&&r>=r(o)){
		sum(o)=(sum(o)*mul+(r(o)-l(o)+1)*add)%p;
		add(o)=(add(o)*mul+add)%p;
		mul(o)=(mul(o)*mul)%p;
		return ;
	}
	spread(o);
	int mid=(l(o)+r(o))>>1;
	if(l<=mid)change(lch,l,r,add,mul);
	if(r>mid)change(rch,l,r,add,mul);
	sum(o)=(sum(lch)+sum(rch))%p;
}
LL ask(int o,int l,int r){
	if(l<=l(o)&&r>=r(o))
		return sum(o);
	spread(o);
	int mid=(l(o)+r(o))>>1;
	LL val=0;
	if(l<=mid)val=(val+ask(lch,l,r))%p;
	if(r>mid)val=(val+ask(rch,l,r))%p;
	return val;
}

int main(){
	int n,m,op,x,y;
	LL k;
	scanf("%d%d%lld",&n,&m,&p);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&op,&x,&y);
		if(op==3)printf("%lld\n",ask(1,x,y));
		else{
			scanf("%lld",&k);
			if(op==1)change(1,x,y,0,k);
			if(op==2)change(1,x,y,k,1);
		}
	}
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值