初学线段树,码风思路清晰,已吐血求调
查看原帖
初学线段树,码风思路清晰,已吐血求调
421265
eastcloud楼主2022/3/21 17:16

rt

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int num[100001];
int n,m,mod;
struct Node{
	int l,r,dat,add1,add2;
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define dat(x) tree[x].dat
	#define m(x) tree[x].add1
	#define p(x) tree[x].add2
}tree[400001];
void build(int p,int l,int r){
	m(p)=1;
	l(p)=l;
	r(p)=r;
	if(l==r){
		dat(p)=num[l];
		return;
	}
	int mid=(l+r)/2;
	build(2*p,l,mid);
	build(2*p+1,mid+1,r);
	dat(p)=(dat(2*p)+dat(2*p+1))%mod;
}
void spread(int p){
	dat(2*p+1)=(m(p)*dat(2*p+1)+(p(p)*(r(p*2+1)-l(p*2+1)+1))%mod)%mod;
	dat(2*p)=(m(p)*dat(2*p)+(p(p)*(r(p*2)-l(p*2)+1))%mod)%mod;
	m(2*p)=(m(p)*m(2*p))%mod;
	m(2*p+1)=(m(p)*m(2*p+1))%mod;
	p(2*p)=(p(2*p)*m(p))%mod+p(p);
	p(2*p+1)=(p(2*p+1)*m(p))%mod+p(p);
	p(p)=0;
	m(p)=1;
}
void chanm(int p,int l,int r,int k){
	if(l(p)>=l && r(p)<=r){
		dat(p)=(dat(p)*k)%mod;
		m(p)=(m(p)*k)%mod;
		p(p)=(p(p)*k)%mod;
		return;
	}
	spread(p);
	int mid=(l(p)+r(p))/2;
	if(l<=mid) chanm(2*p,l,r,k);
	if(r>mid) chanm(2*p+1,l,r,k);
	dat(p)=(dat(p*2)+dat(p*2+1))%mod;
}
void chanp(int p,int l,int r,int k){
	if(l(p)>=l && r(p)<=r){
		p(p)+=k;
		dat(p)=(dat(p)+k*(r(p)-l(p)+1))%mod;
		return;
	}
	cout<<p<<' '<<l<<' '<<r<<endl;
	spread(p);
	int mid=(l(p)+r(p))/2;
	if(l<=mid) chanp(2*p,l,r,k);
	if(r>mid) chanp(2*p+1,l,r,k);
	dat(p)=(dat(p*2)+dat(p*2+1))%mod;
}
int ask(int p,int l,int r){
	if(l(p)>=l && r(p)<=r)return dat(p);
	spread(p);
	int mid=(l(p)+r(p))/2;
	int ans=0;
	if(l<=mid) ans+=ask(p*2,l,r);
	if(r>mid) ans=(ans+ask(p*2+1,l,r))%mod;
	return ans; 
}
int main(){
	cin>>n>>m>>mod;
	for(int i=1;i<=n;i++) cin>>num[i];
	build(1,1,n);
	int x,y,tmp,k;
	for(int i=1;i<=m;i++){
		cin>>tmp;
		if(tmp==1){
			cin>>x>>y>>k;
			chanm(1,x,y,k);
		}
		if(tmp==2){
			cin>>x>>y>>k;
			chanp(1,x,y,k);
		}
		if(tmp==3){
			cin>>x>>y;
			cout<<ask(1,x,y)<<endl;
		}
	}
}
2022/3/21 17:16
加载中...