线段树求助
查看原帖
线段树求助
643820
WangLianda楼主2023/3/21 16:24
#include<bits/stdc++.h>
using namespace std;
int n,m,p,a[100005];
struct node {
	long long id,l,r,sum,add,mul;
} tree[400005];
void build(int id,int l,int r) {
	tree[id].mul=1;
	tree[id].add=0;
	tree[id].l=l;
	tree[id].r=r;
	if(l==r) {
		tree[id].sum=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
	tree[id].sum%=p;
}
void pushdown(int id) {
	tree[id*2].sum=(tree[id*2].sum*tree[id].mul+tree[id].add*(tree[2*id].r-tree[2*id].l+1))%p;
	tree[id*2+1].sum=(tree[id*2+1].sum*tree[id].mul+tree[id].add*(tree[2*id+1].r-tree[2*id+1].l+1))%p;
	//维护懒标记
	tree[id*2].mul=(tree[id*2].mul*tree[id].mul)%p;
	tree[id*2+1].mul=(tree[id*2+1].mul*tree[id].mul)%p;
	tree[id*2].add=(tree[id*2].add*tree[id].mul+tree[id].add)%p;
	tree[id*2+1].add=(tree[id*2+1].add*tree[id].mul+tree[id].add)%p;
	tree[id].mul=1;
	tree[id].add=0;
	return;
}
void update1(int id,int l,int r,int v) { //加法
	if(tree[id].r<l||tree[id].l>r)return;
	if(tree[id].l>=l&&tree[id].r<=r) {
		tree[id].add=(tree[id].add+v)%p;
		tree[id].sum=(tree[id].sum+(tree[id].r-tree[id].l+1)*v)%p;
		return;
	}
	pushdown(id);
	int m=(l+r)/2;
	update1(id*2,l,m,v);
	update1(id*2+1,m+1,r,v);
	tree[id].sum=(tree[id*2].sum+tree[id*2+1].sum)%p;
}
void update2(int id,int l,int r,int v) { //乘法
	if(tree[id].r<l||tree[id].l>r)return;
	if(tree[id].l>=l&&tree[id].r<=r) {
		tree[id].sum=(tree[id].sum*v)%p;
		tree[id].mul=(tree[id].mul*v)%p;
		tree[id].add=(tree[id].add*v)%p;
		return;
	}
	pushdown(id);
	update2(id*2,l,r,v);
	update2(id*2+1,l,r,v);
	tree[id].sum=(tree[id*2].sum+tree[id*2+1].sum)%p;
}
long long query(int id,int l,int r) {
	if(tree[id].r<l||tree[id].l>r)return 0;
	if(tree[id].l>=l&&tree[id].r<=r)return tree[id].sum;
	pushdown(id);
	return (query(id*2,l,r)+query(id*2+1,l,r))%p;
}
int main() {
	scanf("%d%d%d",&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++) {
		int o,x,y,k;
		scanf("%d",&o);
		if(o==2) {
			scanf("%d%d%d",&x,&y,&k);
			update1(1,x,y,k);
		} else if(o==1) {
			scanf("%d%d%d",&x,&y,&k);
			update2(1,x,y,k);
		} else {
			scanf("%d%d",&x,&y);
			printf("%lld\n",query(1,x,y));
		}
	}
	return 0;
}

2023/3/21 16:24
加载中...