30分线段树求调-悬关
查看原帖
30分线段树求调-悬关
664158
ccrui楼主2023/8/11 16:45

线段树求调
30分 对#1,#3,#4

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[100010],n,p;
struct stree{
	long long l,r;
	long long sum,tag,tagc=1;
}t[400010];
void build(int x,int l,int r){
	t[x].l=l,t[x].r=r;
	if(l==r){ 
		t[x].sum=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r); 
	t[x].sum=t[x*2].sum+t[x*2+1].sum;
}
void down(int x){
  	if(t[x].tag){
  		t[x*2].sum=(t[x*2].sum*t[x].tagc%p+(t[x*2].r-t[x*2].l+1)*t[x].tag%p)%p;
  		t[x*2].sum%=p;
		t[x*2+1].sum=(t[x*2+1].sum*t[x].tagc%p+(t[x*2+1].r-t[x*2+1].l+1)*t[x].tag%p)%p;
		t[x*2+1].sum%=p;
  		t[x*2].tagc*=t[x].tagc;
  		t[x*2+1].tagc*=t[x].tagc;
  		t[x*2].tagc%=p;
  		t[x*2+1].tagc%=p;
  		t[x*2].tag*=t[x].tagc; 
  		t[x*2+1].tag*=t[x].tagc;
  		t[x*2].tag%=p;
  		t[x*2+1].tag%=p;
		t[x*2].tag+=t[x].tag; 
  		t[x*2+1].tag+=t[x].tag;
  		t[x*2].tag%=p;
  		t[x*2+1].tag%=p;
  		t[x].tag=0;
  		t[x].tagc=1;
  	}
}
void change(int x,int l,int r,int a){
	if(t[x].l>=l&&t[x].r<=r){
		t[x].tag+=a%p; 
		t[x].tag%=p;
		t[x].sum+=(t[x].r-t[x].l+1)*a%p;
		t[x].sum%=p;
		return;
	}
	if(t[x].l==t[x].r)return;
	down(x);
	int mid=(t[x].l+t[x].r)>>1;
	if(mid>=l)change(x*2,l,r,a);
	if(mid<r)change(x*2+1,l,r,a);
	t[x].sum=(t[x*2].sum+t[x*2+1].sum)%p;
}
void changech(int x,int l,int r,int a){
	if(t[x].l>=l&&t[x].r<=r){
		t[x].tagc*=a;
		t[x].tagc%=p;
		t[x].tag*=a;
		t[x].tag%=p;
		t[x].sum*=a;
		t[x].sum%=p;
		return;
	}
	if(t[x].l==t[x].r)return;
	down(x);
	int mid=(t[x].l+t[x].r)>>1;
	if(mid>=l)changech(x*2,l,r,a);
	if(mid<r)changech(x*2+1,l,r,a);
	t[x].sum=(t[x*2].sum+t[x*2+1].sum)%p;
}
long long ask(int x,int l,int r){
	if(l<=t[x].l&&r>=t[x].r)return t[x].sum%p;
	down(x);
	int mid=(t[x].l+t[x].r)>>1;
	long long sum=0; 
	if(mid>=l)sum+=ask(x*2,l,r)%p;
	if(mid<r)sum+=ask(x*2+1,l,r)%p;
	return sum;
}
signed main(){
	//freopen("P3373_2.in","r",stdin);
	//freopen("s.txt","w",stdout);
  	int n,m,k;
	cin>>n>>m>>p;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]%=p;
	}
  	build(1,1,n);
  	while(m--){
  		string op;
  		int a,b,c;
  		cin>>op>>a>>b;
  		if(op=="1"){
  			cin>>c;
  			changech(1,a,b,c); 
  		}else if(op=="2"){
  			cin>>c;
  			change(1,a,b,c); 
  		}else{
  			cout<<ask(1,a,b)%p<<endl;
  		}
  	}
  	return 0;
}

记录

2023/8/11 16:45
加载中...