萌新刚学线段树样例没过求调
查看原帖
萌新刚学线段树样例没过求调
494192
ChickenDrinkingMilk楼主2023/5/3 11:54
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=100000;
typedef long long ll;
int n,T,P;
struct node{
	ll sum,layc,layj;
}t[N<<2]; 
void pushup(int u){
	t[u].sum=(t[u<<1].sum+t[u<<1|1].sum)%P;
}
void build(int l,int r,int u){
	if (l==r){
		cin>>t[u].sum;
		return ;
	}
	int m=l+r>>1;
	build(l,m,u<<1),build(m+1,r,u<<1|1);
	pushup(u);
}
void pushdown(int l,int r,int u){
	if (l==r||!t[u].layc&&!t[u].layj) return ;
	t[u<<1].layc*=t[u].layc;
	t[u<<1|1].layc*=t[u].layc;
	t[u<<1].layj=t[u<<1].layj*t[u].layc+t[u].layj;
	t[u<<1|1].layj=t[u<<1].layj*t[u].layc+t[u].layj;
	int m=l+r>>1;
	t[u<<1].sum=(t[u<<1].sum*t[u].layc+t[u].layj*(m-l+1))%P;
	t[u<<1|1].sum=(t[u<<1|1].sum*t[u].layc+t[u].layj*(r-m))%P;
	t[u].layc=t[u].layj=0;
}
void addc(int L,int R,int l,int r,int u,ll k){
	if (L<=l&&r<=R){
		t[u].sum*=k;
		t[u].layc+=k;
		t[u].layj*=k;
		return ;
	}
	pushdown(l,r,u);
	int m=l+r>>1;
	if (L<=m) addc(L,R,l,m,u<<1,k);
	if (R>=m+1) addc(L,R,m+1,r,u<<1|1,k);
	pushup(u);
}
void addj(int L,int R,int l,int r,int u,ll k){
	if (L<=l&&r<=R){
		t[u].sum+=k*(r-l+1);
		t[u].layj+=k;
		return ;
	}
	pushdown(l,r,u);
	int m=l+r>>1;
	if (L<=m) addj(L,R,l,m,u<<1,k);
	if (R>=m+1) addj(L,R,m+1,r,u<<1|1,k);
	pushup(u);
}
ll query(int L,int R,int l,int r,int u){
	if (L<=l&&r<=R) return t[u].sum;
	pushdown(l,r,u);
	int m=(l+r)>>1; ll ans=0;
	if (L<=m) ans+=query(L,R,l,m,u<<1);
	if (R>=m+1) ans+=query(L,R,m+1,r,u<<1|1);
	return ans%P;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>T>>P;
	build(1,n,1);
	while (T--){
		ll p,x,y,k;
		cin>>p>>x>>y;
		if (p==1){
			cin>>k;
			addc(x,y,1,n,1,k);
		} else if (p==2){
			cin>>k;
			addj(x,y,1,n,1,k);
		} else {
			cout<<query(x,y,1,n,1)<<'\n';
		}
	}
}

2023/5/3 11:54
加载中...