P6242线段树230分求调
  • 板块学术版
  • 楼主wanghanjia
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/12/23 09:04
  • 上次更新2023/12/23 09:06:13
查看原帖
P6242线段树230分求调
361542
wanghanjia楼主2023/12/23 09:04
#include <bits/stdc++.h>
using namespace std;
long long a[100005],d[400005],b[400005],b2[400005];
long long q;
void build(int l,int r,int p){
	if(l == r){
		d[p] = a[l];
		return;
	}
	long long m = (l+r)/2 ;
	build(l,m,p*2);
	build(m+1,r,p*2+1);
	d[p] = (d[p*2]%q+d[p*2+1]%q)%q;
	return;
}
void update(int l,int r,int c,int s,int t,int p){
	if(l <= s && r >= t){
		
		d[p] = (d[p]+c*(t-s+1))%q;
		b[p] = (b[p]+c)%q;
		return;
	}
	long long m = (s+t)/2 ;
	if(b2[p] !=1 && s != t){
		d[p*2] = (d[p*2]*b2[p])%q;
		d[p*2+1] = (d[p*2+1]*b2[p])%q;
		b[p*2] =(b[p*2]*b2[p])%q;
		b[p*2+1] = (b[p*2+1]*b2[p])%q;
		b2[p*2] = (b2[p*2]*b2[p])%q;
		b2[p*2+1] = (b2[p*2+1]*b2[p])%q;
		b2[p] = 1;
	}
	if(b[p] != 0 && s != t){
		d[p*2] = (d[p*2]+((b[p]%q)*((m-s+1)%q)))%q;
		d[p*2+1] = (d[p*2+1]+((b[p]%q)*((t-m)%q))%q)%q;
		b[p*2] = (b[p*2]+b[p])%q;
		b[p*2+1] += (b[p*2+1]+b[p])%q;
		b[p] = 0;
	}
	if(l <= m) update(l,r,c,s,m,p*2);
	if(m+1 <= r) update(l,r,c,m+1,t,p*2+1);
	d[p] = (d[p*2]%q + d[p*2+1]%q)%q;
	return;
}
void updatex(int l,int r,int c,int s,int t,int p){
	if(l <= s && r >= t){
		d[p] = d[p]*c%q;
		b2[p] = b2[p]*c%q;
		b[p] = b[p]*c%q;
		return;
	}
	long long m = (s+t)/2 ;
	if(b2[p] !=1 && s != t){
		d[p*2] = (d[p*2]*b2[p])%q;
		d[p*2+1] = (d[p*2+1]*b2[p])%q;
		b[p*2] =(b[p*2]*b2[p])%q;
		b[p*2+1] = (b[p*2+1]*b2[p])%q;
		b2[p*2] = (b2[p*2]*b2[p])%q;
		b2[p*2+1] = (b2[p*2+1]*b2[p])%q;
		b2[p] = 1;
	}
	if(b[p] != 0 && s != t){
		d[p*2] = (d[p*2]+((b[p]%q)*((m-s+1)%q)))%q;
		d[p*2+1] = (d[p*2+1]+((b[p]%q)*((t-m)%q))%q)%q;
		b[p*2] = (b[p*2]+b[p])%q;
		b[p*2+1] += (b[p*2+1]+b[p])%q;
		b[p] = 0;
	}
	if(l <= m)updatex(l,r,c,s,m,p*2);
	if(m+1 <= r)updatex(l,r,c,m+1,t,p*2+1);
	d[p] = (d[p*2]%q + d[p*2+1]%q)%q;
	return;
}
long long sumget(int l,int r,int s,int t,int p){
	if(l <= s && r >= t){
		return (d[p]%q);
	}
	long long m = (s+t)/2 ;
	if(b2[p] !=1 && s != t){
		d[p*2] = d[p*2]*b2[p]%q;
		d[p*2+1] = d[p*2+1]*b2[p]%q;
		b[p*2] =b[p*2]*b2[p]%q;
		b[p*2+1] = b[p*2+1]*b2[p]%q;
		b2[p*2] = b2[p*2]*b2[p]%q;
		b2[p*2+1] = b2[p*2+1]*b2[p]%q;
		b2[p] = 1;
	}
	if(b[p] != 0 && s != t){
		d[p*2] = (d[p*2]+((b[p]%q)*((m-s+1)%q)))%q;
		d[p*2+1] = (d[p*2+1]+((b[p]%q)*((t-m)%q))%q)%q;
		b[p*2] = (b[p*2]+b[p])%q;
		b[p*2+1] += (b[p*2+1]+b[p])%q;
		b[p] = 0;
	}
	long long sum = 0;
	if(l <= m) sum += sumget(l,r,s,m,p*2)%q;
	if(m < r) sum += sumget(l,r,m+1,t,p*2+1)%q; 
	return (sum%q);
}
int main(){
	long long n,m;
	cin >> n >> m >> q;
	for(int i = 1; i <= n; i++){
		cin >> a[i];
		a[i] %= q;
		b2[i] = 1;
	}
	build(1,n,1);
	while(m--){
		int z,x,y;
		cin >> z >> x >> y;
		if(z == 1){
			int k;
			cin >> k;
			updatex(x,y,k,1,n,1);
		} 
		else if(z == 2){
			int k;
			cin >> k;
			update(x,y,k,1,n,1);
		} else {
			cout << sumget(x,y,1,n,1) << endl;
		}
	}
	return 0;
}
2023/12/23 09:04
加载中...