蒟蒻求助线段树2写挂了
查看原帖
蒟蒻求助线段树2写挂了
399150
ShunpowerSHUN理成张楼主2021/8/26 08:59

RT,已经知道要先乘后加了,所以下传懒标记的时候先下传的乘法标记再下传的加法标记。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,mod;
ll a[100010],b[400010],lazyflag[400010],lazyflag1[400010];
void build(ll p,ll l,ll r){
	if(l==r){
		b[p]=a[l];
		return;
	}
	ll m=(l+r)/2;
	build(p*2,l,m);
	build(p*2+1,m+1,r);
	b[p]=b[p*2]+b[p*2+1];
}
void addflag(ll p,ll l,ll r,ll num){
	lazyflag[p]+=num%mod;
//	b[p]*=lazyflag1[p/2];
	b[p]+=(num*(r-l+1))%mod;
} 
void addflag1(ll p,ll l,ll r,ll num){
	lazyflag1[p]*=num%mod;
	b[p]*=num%mod;
} 
void revise(ll l1,ll r1,ll l,ll r,ll p,ll num){
	if(l1<=l&&r<=r1){
		b[p]+=(num*(r-l+1))%mod;
		lazyflag[p]+=num;
		return;
	}
	ll m=(l+r)/2;
	addflag(p*2,l,m,lazyflag[p]);
	addflag(p*2+1,m+1,r,lazyflag[p]);
	lazyflag[p]=0;
	if(l1<=m){
		revise(l1,r1,l,m,p*2,num);
	} 
	if(r1>m){
		revise(l1,r1,m+1,r,p*2+1,num);
	}
	b[p]=(b[p*2]+b[p*2+1])%mod;
}
void revise1(ll l1,ll r1,ll l,ll r,ll p,ll num){
	if(l1<=l&&r<=r1){
		b[p]*=num%mod;
		lazyflag1[p]*=num%mod;
		return;
	}
	ll m=(l+r)/2;
	addflag1(p*2,l,m,lazyflag1[p]);
	addflag1(p*2+1,m+1,r,lazyflag1[p]);
	lazyflag1[p]=1;
	if(l1<=m){
		revise1(l1,r1,l,m,p*2,num);
	} 
	if(r1>m){
		revise1(l1,r1,m+1,r,p*2+1,num);
	}
	b[p]=(b[p*2]+b[p*2+1])%mod;
}
ll section(ll l1,ll r1,ll l,ll r,ll p){
	ll sum=0;
	if(l1<=l&&r<=r1){
		return b[p]%mod;
	}
	ll m=(l+r)/2;
	addflag1(p*2,l,m,lazyflag1[p]);
	addflag1(p*2+1,m+1,r,lazyflag1[p]);
	lazyflag1[p]=1;
	addflag(p*2,l,m,lazyflag[p]);
	addflag(p*2+1,m+1,r,lazyflag[p]);
	lazyflag[p]=0;
	if(l1<=m){
		sum+=section(l1,r1,l,m,p*2);
	}
	if(r1>m){
		sum+=section(l1,r1,m+1,r,p*2+1);
	}
	return sum%mod;
}
int main(){
	cin>>n>>m>>mod;
	for(int i=1;i<=400010;i++){
		lazyflag1[i]=1;
	}
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]%=mod;
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int x;
		cin>>x;
		if(x==1){
			int x1,x2,k;
			cin>>x1>>x2>>k;
			revise1(x1,x2,1,n,1,k);
		}
		else if(x==2){
			int x1,x2,k;
			cin>>x1>>x2>>k;
			revise(x1,x2,1,n,1,k);
		}
		else{
			int x1,x2;
			cin>>x1>>x2;
			cout<<section(x1,x2,1,n,1)<<endl;
		}
	}
	return 0;
}

这是代码,求 dalao 指出写挂的地方,本地测了几个小数据都能 A 过

2021/8/26 08:59
加载中...