线段树求调!
查看原帖
线段树求调!
695230
EnderWaveWolf楼主2022/4/8 15:57

自我感觉应该是在40-55行有错误,区间乘我是按区间加来写的(把加改成了乘,标记还是加)试过了只过了样例其他全都WA(QWQ),大佬看看区间乘有什么问题,或者我这样写就不对?

#include<iostream>
using namespace std;
#define q 571373
#define MAX 500005
long long d[MAX * 4];//储存原数组数据 
long long a[MAX];//原数组 
long long b[MAX * 4], c[MAX * 4]; //b用来储存+lazy,c储存*lazy 

//建树 
void build(int s,int t,int p){//s,t表示当前区间为[s,t],p表示数组d下标 
	if (s == t){//当当前区间只包含一个数据是,直接赋a的值 
		d[p] = a[s] % q;
		return;
	}
	int m = (s + ((t - s) >> 1)) % q;//m为中间值 
	build(s ,m ,p * 2),build(m + 1 ,t , p * 2 + 1);//p*2为左儿子,p*2+1为右儿子 
	d[p] = (d[2 * p] % q + d[2 * p + 1] % q) % q; 
	return;
} 

//区间修改 +
void update(int l,int r,int c,int s,int t,int p){//l,r为查询区间[l,r],c为+lazy 
	if (l <= s && t <= r){ //当当前区间区间为查询区间的子集时 
		d[p] += (1ll * (t - s + 1)) * c % q,b[p] += c % q; //更新当前区间的值,并做标记 
		return ;
	} 
	int m = (s + ((t - s) >> 1)) % q;
	if  (b[p] && s != t){//当有标记且当前区间不止包含一个数据时 
	    d[p * 2] += (1ll * (m - s + 1) * b[p]) % q,d[p * 2 + 1] += (1ll * (t - m) * b[p]) % q;//更新两个儿子的值 
		b[p * 2] += b[p] % q,b[p * 2 + 1] += b[p] % q;//并放下标记 
		b[p] = 0;//标记清除 
	}
	if (l <= m) update(l ,r ,c ,s ,m ,p * 2) ;//如果与左儿子有交集,修改左儿子 
	if (r > m) update(l ,r ,c ,m + 1,t ,p * 2 + 1) ;//如果与右儿子有交集,修改右儿子
	d[p] = (d[2 * p] % q + d[2 * p + 1] % q) % q;
	return ;
}

//区间乘 
void update2(int l, int r, int b, int s, int t, int p){//l,r为查询区间[l,r],b为*lazy
	if (l <= s && t <= r) {//当当前区间区间为查询区间的子集时
		d[p] = (1ll *d[p] * b) % q, c[p] += b % q;//更新当前区间的值,并做标记
		return;
	}
	int m = (s + ((t - s) >> 1)) % q;
	if (c[p] && s != t) {//当有标记且当前区间不止包含一个数据时
		d[p * 2] = (1ll * d[p * 2] * c[p]) % q, d[p * 2 + 1] *= (1ll * d[p * 2 + 1] * c[p]) % q;//更新两个儿子的值
		c[p * 2] += c[p] % q, c[p * 2 + 1] += c[p] % q;//并放下标记 
		c[p] = 0;//标记清除
	}
	if (l <= m ) update2(l, r, b, s, m, p * 2) ;//如果与左儿子有交集,修改左儿子
	if (r > m ) update2(l, r, b, m + 1, t, p * 2 + 1) ;//如果与右儿子有交集,修改右儿子
	d[p] = (d[2 * p] % q + d[2 * p + 1] % q) % q;
	return;
}

//区间求和(区间查询) 
long long getsum(int l,int r,int s,int t,int p){
	if (l <= s && r >= t) 
	    return d[p] % q;
	int m = (s + ((t - s) >> 1)) % q;
	if (b[p]) {
		d[p * 2] += (1ll * b[p] * (m - s + 1)) % q,d[p * 2 + 1] += (1ll * b[p] * (t - m)) % q, 
		    b[p * 2] += b[p] % q,b[p * 2 + 1] += b[p] % q;
		b[p] = 0;
	}
	long long sum = 0;
	if (l <= m) sum += getsum(l ,r ,s ,m ,p * 2) ; 
	if (r > m) sum += getsum(l ,r ,m + 1 ,t ,p * 2 + 1) ;
	return sum % q;
}

int main(){
	int n ,m ,i ,p;
	int x ,y ,k ;
	cin>>n>>m>>p;
	for (int j = 1;j <= n;j ++)
	    cin>>a[j];
	build(1 ,n ,1);
	while(m--) {
		cin>>i;
		switch(i){
			case 1:{
				cin>>x>>y>>k;
				update2(x ,y ,k ,1 ,n ,1 );
				break;
			}
			case 2:{
				cin>>x>>y>>k;
				update(x ,y ,k ,1 ,n ,1 );
				break;
			}
			case 3:{
				cin>>x>>y;
                cout<<getsum(x ,y ,1 ,n ,1 ) % p<<endl;
				break;
			}
		}	
	}
	return 0;
} 
2022/4/8 15:57
加载中...