0分线段树求条(样例已过/一关)求帮改过
查看原帖
0分线段树求条(样例已过/一关)求帮改过
1063855
xu_zhihao楼主2024/7/16 20:10
#include<bits/stdc++.h>
using namespace std;
struct node{//线段树结结构 
	long long l;
	long long r;
	long long sum=0;
	long long tag1=0;
	long long tag2=1;
};
node tree[1000010];
long long a[1000010];
long long ret=0;
long long n,m,p;
void make_tree(long long id,long long l,long long r){//建树 
    //cout<<id<<endl;
	tree[id].l=l;
	tree[id].r=r;
	if(l==r){
		tree[id].sum=a[l];
		return;
	}
	long long mid=(l+r)/2;
	make_tree(id*2,l,mid);
	make_tree(id*2+1,mid+1,r);
	return;
}
void push_up(long long id){//更正答案 
	tree[id].sum=(tree[id*2].sum%p)+(tree[id*2+1].sum)%p;
	tree[id].sum%=p;
	return;
}
void push_down(long long id){//下传懒标记 
    if(!tree[id].tag1 && tree[id].tag2==1){
    	return;
	}
	tree[id*2].sum*=tree[id].tag2;
	tree[id*2].sum+=tree[id].tag1*(tree[id*2].r-tree[id*2].l+1);
	tree[id*2].sum%=p;
	
	
	tree[id*2+1].sum*=tree[id].tag2;
	tree[id*2+1].sum+=tree[id].tag1*(tree[id*2+1].r-tree[id*2+1].l+1);
	tree[id*2+1].sum%=p;
	
	
	//tree[id*2].tag1+=tree[id].tag1;
	tree[id*2].tag2=(tree[id*2].tag2*tree[id].tag2)%p;
	tree[id*2+1].tag2=(tree[id*2+1].tag2*tree[id].tag2)%p;
	
	tree[id*2].tag1=(tree[id*2].tag1+tree[id].tag1)%p;
	tree[id*2+1].tag1=(tree[id*2+1].tag1+tree[id].tag1)%p;
	tree[id].tag1=0;
	tree[id].tag2=1;
	return;
}
long long ans_l,ans_r,ans;
void add(long long id){//对于加 
	if(tree[id].r<ans_l || tree[id].l>ans_r){
		return;
	}
	if(tree[id].l>=ans_l && tree[id].r<=ans_r){
		tree[id].sum=tree[id].sum*ans%p;
		tree[id].tag2=tree[id].tag2*ans%p;
		tree[id].tag1=tree[id].tag1*ans%p;
		return;
	}
	if(tree[id].l==tree[id].r){
		return;
	}
	push_down(id);
	add(id*2);
	add(id*2+1); 
	push_up(id);
	return;
}
void mul(long long id){//对于乘 
	if(tree[id].r<ans_l || tree[id].l>ans_r){
		return;
	}
	if(tree[id].l>=ans_l && tree[id].r<=ans_r){
	    tree[id].sum=(tree[id].sum+(tree[id].r-tree[id].l+1)*ans)%p;
		tree[id].tag1=(tree[id].tag1+ans)%p;
		return;
	}
	if(tree[id].l==tree[id].r){
		return;
	}
	push_down(id);
	mul(id*2);
	mul(id*2+1); 
	push_up(id);
	return;
}
void work_tree(long long id){//加工区间和 
    //cout<<ans_l<<" "<<ans_r<<endl;
	if(tree[id].r<ans_l || tree[id].l>ans_r){
		return;
	}
	if(tree[id].l>=ans_l && tree[id].r<=ans_r){
		ret+=tree[id].sum;
		ret%=p; 
		return;
	}
	if(tree[id].l==tree[id].r){
		return;
	}
	push_down(id);
	work_tree(id*2);
	work_tree(id*2+1); 
	push_up(id);
	
}
void Init(long long x,long long y,long long k){
	ans_l=x;
	ans_r=y;
	ans=k%p;
	ret=0;
}
int main(){
	//reopen("C:\\Users\\Administrator\\Desktop\\uoj1.in","r",stdin);
	scanf("%lld%lld%lld",&n,&m,&p);
	for(long long i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		a[i]%=p;
	}
	make_tree(1,1,n);
	while(m--){
		long long op;
		scanf("%d",&op);
		if(op==1){
			long long x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			Init(x,y,k);
			add(1);
		}
		if(op==2){
			long long x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			Init(x,y,k);
			mul(1);
		}
		if(op==3){
			long long x,y;
			scanf("%lld%lld",&x,&y);
			Init(x,y,114514);
			work_tree(1);
			printf("%lld\n",ret);
		}
	}
	return 0;
}
2024/7/16 20:10
加载中...