自我感觉应该是在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;
}