社区讨论

求大佬帮助!

P3373【模板】线段树 2参与者 2已保存回复 3

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lo8fgrmp
此快照首次捕获于
2023/10/27 17:45
2 年前
此快照最后确认于
2023/10/27 17:45
2 年前
查看原帖
照着题解的线段树敲的,样例没过,看了半天没看出来,求调。
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[100009],p;
struct lp{
	int v,mul,add;
}s[400009];
void build(int k,int l,int r){
	s[k].mul=1;
	s[k].add=0;
	if(l==r){
		s[k].v=a[l]%p;
		return;
	}
	int mid=l+r>>1;
	build(2*k,l,mid);
	build(2*k+1,mid+1,r);
	s[k].v=(s[k*2].v+s[k*2+1].v)%p;
}
void pushdown(int k,int l,int r,int mid){
	s[k*2].v=(s[k*2].v*s[k].mul+s[k].add*(m-l+1))%p;
	s[k*2+1].v=(s[k*2+1].v*s[k].mul+s[k].add*(r-m))%p;
	s[k*2].mul=(s[k*2].mul*s[k].mul)%p;
	s[k*2+1].mul=(s[k*2+1].mul*s[k].mul)%p;
	s[k*2].add=(s[k*2].add*s[k].mul+s[k].add)%p;
	s[k*2+1].add=(s[k*2+1].add*s[k].mul+s[k].add)%p;
	s[k].mul=1;
	s[k].add=0;
}
void quick_mul(int k,int l,int r,int x,int y,int v){
	if(x>r||y<l) return;
	if(x<=l&&y>=r){
		s[k].v=(s[k].v*v)%p;
		s[k].mul=(s[k].mul*v)%p;
		s[k].add=(s[k].add*v)%p;
		return;
	}
	int mid=l+r>>1;
	pushdown(k,l,r,mid);
	quick_mul(k*2,l,mid,x,y,v);
	quick_mul(k*2+1,mid+1,r,x,y,v);
	s[k].v=(s[k*2].v+s[k*2+1].v)%p;
}
void quick_pls(int k,int l,int r,int x,int y,int v){
	if(x>r||y<l) return;
	if(x<=l&&y>=r){
		s[k].add=(s[k].add+v)%p;
		s[k].v=(s[k].v+v*(r-l+1))%p;
		return;
	}
	int mid=l+r>>1;
	pushdown(k,l,r,mid);
	quick_pls(k*2,l,mid,x,y,v);
	quick_pls(k*2+1,mid+1,r,x,y,v);
	s[k].v=(s[k*2].v+s[k*2+1].v)%p;
}
int quick_qee(int k,int l,int r,int x,int y){
	if(x>r||y<l) return 0;
	if(l>=x&&r<=y) return s[k].v;
	int mid=l+r>>1;
	pushdown(k,l,r,mid);
	return ((quick_qee(k*2,l,mid,x,y)+quick_qee(k*2+1,mid+1,r,x,y))%p);
}
signed main(){
	scanf("%lld%lld%lld",&n,&m,&p);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int op;
		scanf("%lld",&op);
		if(op==1){
			int t,g,c;
			scanf("%lld%lld%lld",&t,&g,&c);
			quick_mul(1,1,n,t,g,c);
			int j=1;
/*			while(s[j].v!=0){
				cout<<s[j].v<<" ";
				j++;
			}
			cout<<endl;*/
		}
		if(op==2){
			int t,g,c;
			scanf("%lld%lld%lld",&t,&g,&c);
			quick_pls(1,1,n,t,g,c);
/*			int j=1;
			while(s[j].v!=0){
				cout<<s[j].v<<" ";
				j++;
			}
			cout<<endl;*/
		}
		if(op==3){
			int t,g;
			scanf("%lld%lld",&t,&g);
			printf("%lld\n",quick_qee(1,1,n,t,g));
		}
	}
	return 0;
}

回复

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

正在加载回复...