社区讨论

线段书2求助

灌水区参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@m39uht6t
此快照首次捕获于
2024/11/09 15:29
去年
此快照最后确认于
2025/11/04 15:03
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
struct node{
	long long p,c;
}tax[400005];
int n,q,k;
long long mod;
struct node2{
	int l,r;
	long long sum;
}tree[400005];
long long a[100005];
void build(int l,int r,int x){
	if(r==l){
		tree[x].sum=a[l];
		tree[x].l=l;
		tree[x].r=r;
		return ;
	}
	int mid=(l+r)/2;
	build(l,mid,x*2);
	build(mid+1,r,x*2+1);
	tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;
}
void push_down(int l,int r,int x){
	if(tax[x].c!=0){
		tax[x*2].c*=tax[x].c;
		tax[x*2].c%=mod;
		tax[x*2+1].c*=tax[x].c;
		tax[x*2+1].c%=mod;
		tree[x*2].sum=tree[x*2].sum*tax[x].c%mod;
		tree[x*2+1].sum=tree[x*2+1].sum*tax[x].c%mod;
	}
	if(tax[x].p!=0){
		tax[x*2].p+=tax[x].p;
		tax[x*2+1].p+=tax[x].p;
		tree[x*2].sum+=tax[x].p*(tree[x*2].r-tree[x*2].l+1);
		tree[x*2+1].sum+=tax[x].p*(tree[x*2+1].r-tree[x*2+1].l+1);
	}
	tax[x].c=1;
	tax[x].p=0;
}
void add1(int l,int r,int a,int b,int x){
	if(a<=l && r<=b){
		push_down(l,r,x);
		tax[x].p+=k;
		tax[x].p%=mod;
		tree[x].sum+=k*(r-l+1);
		tree[x].sum%=mod;
		return ;
	}
	push_down(l,r,x);
	int mid=(l+r)/2;
	if(mid>=a) add1(l,mid,a,b,x*2);
	if(mid<b) add1(mid+1,r,a,b,x*2+1);
	tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;
}
void add2(int l,int r,int a,int b,int x){
	if(a<=l && r<=b){
		push_down(l,r,x);
		tax[x].c*=k;
		tax[x].c%=mod;
		tree[x].sum*=k;
		tree[x].sum%=mod;
		return ;
	}
	push_down(l,r,x);
	int mid=(l+r)/2;
	if(mid>=a) add2(l,mid,a,b,x*2);
	if(mid<b) add2(mid+1,r,a,b,x*2+1);
	tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;	
}
long long merge(int l,int r,int a,int b,int x){
	if(a<=l && r<=b){
		push_down(l,r,x);
		return tree[x].sum;
	}
	push_down(l,r,x);
	int mid=(l+r)/2;
	long long ret=0;
	if(mid>=a) ret+=merge(l,mid,a,b,x*2);
	if(mid<b) ret+=merge(mid+1,r,a,b,x*2+1);
	ret%=mod;
	return ret%mod;	
}
int main(){
	
	scanf("%d%d%lld",&n,&q,&mod);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}	
	build(1,n,1);//cerr<<"aaa";
	int a,b,t;
	for(int i=1;i<=q;i++){
		scanf("%d%d%d",&t,&a,&b);
		if(t==2){
			scanf("%d",&k);
			add1(1,n,a,b,1);
			cout<<merge(1,n,a,b,1)<<endl;
		}else if(t==1){
			scanf("%d",&k);
			add2(1,n,a,b,1);
			cout<<merge(1,n,a,b,1)<<endl;
			
		}else{
			cout<<merge(1,n,a,b,1)<<endl;
		}
	}
	return 0;
}/*
5 5 10000
1 1 1 1 1
2 1 4 5
1 2 5 2
*/

回复

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

正在加载回复...