社区讨论

求大佬帮忙查一下线段树2的错 (第二弹)

灌水区参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@locyel2h
此快照首次捕获于
2023/10/30 21:46
2 年前
此快照最后确认于
2023/11/05 08:08
2 年前
查看原帖
rt
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+1;
struct Node{
    int l,r,sum,ad,cf;
}tree[4*maxn];
char s;
int n,m,p,x,y,k;
int a[maxn];
void pushdown(int i){
	//先更新子节点的值 
	tree[i<<1].sum=(tree[i<<1].sum*tree[i].cf+(tree[i<<1].r-tree[i<<1].l+1)*tree[i].ad)%p;
	tree[i<<1|1].sum=(tree[i<<1|1].sum*tree[i].cf+(tree[i<<1|1].r-tree[i<<1|1].l)*tree[i].ad)%p;
	//更新子节点的lazytag
	tree[i<<1].ad=(tree[i<<1].ad*tree[i].cf+tree[i<<1].ad)%p;
	tree[i<<1].cf=(tree[i<<1].cf*tree[i].cf)%p; 
	tree[i<<1|1].ad=(tree[i<<1|1].ad*tree[i].cf+tree[i<<1|1].ad)%p;
	tree[i<<1|1].cf=(tree[i<<1|1].cf*tree[i].cf)%p; 
	//父节点的lazytag还原
	tree[i].cf=1;
	tree[i].ad=0;
	return; 
} 
void build(int k,int l,int r){
	tree[k].cf=1;
	tree[k].ad=0;
	tree[k].l=l;
	tree[k].r=r;
	if(l==r){
		tree[k].sum=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p;
}
void change1(int i,int l,int r,int k){
	if(tree[i].l>=l&&tree[i].r<=r){
		tree[i].sum=(tree[i].sum*k)%p;
		tree[i].ad=(tree[i].ad*k)%p;
		tree[i].cf=(tree[i].cf*k)%p;
		return;
	}
	pushdown(i);
	if(tree[i<<1].r>=l)change1(i<<1,l,r,k);
	if(tree[i<<1|1].l<=r)change1(i<<1|1,l,r,k);
	tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p; 
	return;
}
void change2(int i,int l,int r,int k){
	if(tree[i].l>=l&&tree[i].r<=r){
		tree[i].ad=(tree[i].ad+k)%p;
		tree[i].sum=(tree[i].sum+k*(tree[i].r-tree[i].l+1))%p;
		return;
	}
	pushdown(i);
	if(tree[i<<1].r>=l)change1(i<<1,l,r,k);
	if(tree[i<<1|1].l<=r)change1(i<<1|1,l,r,k);
	tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p; 
	return;
}
int find(int i,int l,int r){
	if(tree[i].l>=l&&tree[i].r<=r)return tree[i].sum;
	pushdown(i);
	int ans=0;
	if(l<=tree[i*2].r)ans=(ans+find(i*2,l,r))%p;
	if(r>=tree[i*2+1].l)ans=(ans+find(i*2+1,l,r))%p;
	return ans%p;
}
int main(){
    cin>>n>>m>>p;
    for(int i=1;i<=n;i++)cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=m;i++){
    	cin>>s;
    	if(s=='1'){
			cin>>x>>y>>k;
			change1(1,x,y,k);
    	}
    	if(s=='2'){
			cin>>x>>y>>k;
			change2(1,x,y,k);
    	}
    	if(s=='3'){
			cin>>x>>y;
			cout<<(find(1,x,y))%p<<endl;
    	}
    }
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...