社区讨论

调了一天了,还是1、9、10三个点WA,求助

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

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lo8d84za
此快照首次捕获于
2023/10/27 16:42
2 年前
此快照最后确认于
2023/10/27 16:42
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 8000010;
int n,m,mo;
int a[N];
struct Node
{
	int l,r,c_tag,j_tag,sum;//j_tag:加法懒惰标记,c_tag:乘法懒惰标记 
}t[N];
void pushup(int rt)
{
	t[rt].sum = t[rt<<1].sum+t[rt<<1|1].sum;
	t[rt].sum %= mo;
}
void build(int rt,int l,int r)
{
	t[rt].l = l,t[rt].r = r;
	int mid = (l+r)>>1;
	t[rt].c_tag = 1;
	if(l == r)
	{
		t[rt].sum = a[l]%mo;
		return;
	}
	build(rt<<1,l,mid),build(rt<<1|1,mid+1,r);
	pushup(rt);
}
void pushdown(int rt)
{
	if(t[rt].c_tag==0 && t[rt].j_tag==0) return;
	int l = t[rt].l,r = t[rt].r,mid = (l+r)>>1;
	t[rt<<1].sum = ((t[rt<<1].r-t[rt<<1].l+1)*t[rt].j_tag + t[rt<<1].sum*t[rt].c_tag)%mo;
	t[rt<<1|1].sum = ((t[rt<<1|1].r-t[rt<<1|1].l+1)*t[rt].j_tag + t[rt<<1|1].sum*t[rt].c_tag)%mo;
	t[rt<<1].c_tag = (t[rt<<1].c_tag * t[rt].c_tag)%mo;
	t[rt<<1|1].c_tag = (t[rt<<1|1].c_tag * t[rt].c_tag)%mo;
	t[rt<<1].j_tag = (t[rt<<1].j_tag*t[rt].c_tag + t[rt].j_tag)%mo;
	t[rt<<1|1].j_tag = (t[rt<<1|1].j_tag*t[rt].c_tag + t[rt].j_tag)%mo;
	t[rt].j_tag = 0;
	t[rt].c_tag = 1;
}
void updates1(int rt,int start,int end,int x)//乘法操作(j_tag+sum)*k = j_tag*k+sum+k
{
	int l = t[rt].l,r = t[rt].r,mid = (l+r)>>1;
	if(start<=l && r<=end)
	{
		t[rt].j_tag = (t[rt].j_tag*x)%mo;
		t[rt].c_tag = (t[rt].c_tag*x)%mo;
		t[rt].sum = (t[rt].sum*x)%mo;
		return;
	}	
	pushdown(rt);
	if(start <= mid) updates1(rt<<1,start,end,x);
	if(end > mid) updates1(rt<<1|1,start,end,x);
	pushup(rt);
}
void updates2(int rt,int start,int end,int x)//加法操作
{
	int l = t[rt].l,r = t[rt].r,mid = (l+r)>>1;
	if(start<=l && r<=end)
	{
		t[rt].j_tag = (t[rt].j_tag+x)%mo;
		t[rt].sum = (t[rt].sum+(r-l+1)*x)%mo;
		return; 
	}	
	pushdown(rt);
	if(start <= mid) updates2(rt<<1,start,end,x);
	if(end > mid) updates2(rt<<1|1,start,end,x);
	pushup(rt); 
} 
int query(int rt,int start,int end)
{
	if(start > end) return 0;
	int l = t[rt].l,r = t[rt].r,mid = (l+r)>>1;
	if(start<=l && end>=r) return t[rt].sum%mo;
	pushdown(rt);
	int res = 0;
	if(start <= mid) res += query(rt<<1,start,end),res %= mo;
	if(end > mid) res += query(rt<<1|1,start,end),res %= mo;
	return res;
}
signed main()
{
	//freopen("P3372_2.in","r",stdin);
	//freopen("P3372_2.out","w",stdout);
	cin>>n>>m>>mo;
	for(int i=1; i<=n; i++) cin>>a[i];
	build(1,1,n);
	for(int i=1; i<=m; i++)
	{
		int op,x,y,k; cin>>op>>x>>y;
		if(op == 1)
		{
			cin>>k; updates1(1,x,y,k);
		} else if(op == 2)
		{
			cin>>k; updates2(1,x,y,k);
		}else
		{
			cout<<query(1,x,y)%mo<<endl;
		}
	}
	return 0;
}

回复

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

正在加载回复...