title

线段树

懒标记+乘法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
int n,m;
int ans,p,num[3000100];
struct Node{
	int l,r,num;
	int sum,lazy,mul;
} tr[4000100];
void pushup(int now){
	tr[now].sum=(tr[now<<1].sum+tr[now<<1|1].sum)%p;
}
void buildtree(int l,int r,int now){
	tr[now].l=l;
	tr[now].r=r;
	tr[now].mul=1;
	if(l==r){
		scanf("%lld",&tr[now].sum);
		return;
	}
	int mid=(l+r)>>1;
	buildtree(l,mid,now<<1);
	buildtree(mid+1,r,now<<1|1);
	pushup(now);
}
void pushdown(int now){
	tr[now<<1].mul=(tr[now<<1].mul*tr[now].mul)%p;
	tr[now<<1|1].mul=(tr[now<<1|1].mul*tr[now].mul)%p;
	tr[now<<1].lazy=(tr[now<<1].lazy*tr[now].mul+tr[now].lazy)%p;
	tr[now<<1|1].lazy=(tr[now<<1|1].lazy*tr[now].mul+tr[now].lazy)%p;
	tr[now<<1].sum=(tr[now<<1].sum*tr[now].mul+(tr[now<<1].r-tr[now<<1].l+1)*tr[now].lazy)%p;
	tr[now<<1|1].sum=(tr[now<<1|1].sum*tr[now].mul+(tr[now<<1|1].r-tr[now<<1|1].l+1)*tr[now].lazy)%p;
	tr[now].lazy=0;
	tr[now].mul=1;
}
void update(int l,int r,int now,int val){
	if(tr[now].l==l&&tr[now].r==r){
		tr[now].lazy=(tr[now].lazy+val)%p;
		tr[now].sum=(tr[now].sum+(tr[now].r-tr[now].l+1)*val)%p;
		return;
	}
	if(tr[now].lazy||tr[now].mul!=1) pushdown(now);
	int mid=(tr[now].l+tr[now].r)>>1;
	if(l>mid) update(l,r,now<<1|1,val);
	else if(mid>=r) update(l,r,now<<1,val);
	else{
		update(l,mid,now<<1,val);
		update(mid+1,r,now<<1|1,val);
	}
	pushup(now);
}
void multi(int l,int r,int now,int val){
	if(tr[now].l==l&&tr[now].r==r){
		tr[now].lazy=(tr[now].lazy*val)%p;
		tr[now].mul=(tr[now].mul*val)%p;
		tr[now].sum=(tr[now].sum*val)%p;
		return;
	}
	if(tr[now].lazy||tr[now].mul!=1) pushdown(now);
	int mid=(tr[now].l+tr[now].r)>>1;
	if(l>mid) multi(l,r,now<<1|1,val);
	else if(mid>=r) multi(l,r,now<<1,val);
	else{
		multi(l,mid,now<<1,val);
		multi(mid+1,r,now<<1|1,val);
	}
	pushup(now);
}
void check(int l,int r,int now){
	if(tr[now].l==l&&tr[now].r==r){
		ans=(tr[now].sum+ans)%p;
		return;
	}
	if(tr[now].lazy||tr[now].mul!=1) pushdown(now);
	int mid=(tr[now].l+tr[now].r)>>1;
	if(l>mid) check(l,r,now<<1|1);
	else if(mid>=r) check(l,r,now<<1);
	else{
		check(l,mid,now<<1);
		check(mid+1,r,now<<1|1);
	}
	pushup(now);
}
signed main(){
	int k;
	scanf("%d%d%lld",&n,&m,&p);
	buildtree(1,n,1);
	for(int i=1,cas,x,y;i<=m;i++){
		scanf("%d%d%d",&cas,&x,&y);
		if(cas==1){
			scanf("%lld",&k);
			multi(x,y,1,k);
		}
		else if(cas==2){
			scanf("%lld",&k);
			update(x,y,1,k);
		}
		else{
			ans=0;
			check(x,y,1);
			printf("%lld\n",ans);
		}
	}
	return 0;
}
posted @ 2018-09-10 01:34  Horrigue_JyowYang  阅读(136)  评论(0编辑  收藏  举报