求助线段树模板2(玄关)
  • 板块灌水区
  • 楼主zjy102512
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/10/15 21:47
  • 上次更新2024/10/16 08:01:48
查看原帖
求助线段树模板2(玄关)
931394
zjy102512楼主2024/10/15 21:47

过了#1 #3 #4,问题应该就是在取模上,有没有dalao帮忙看一下:(

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
int n,m;
ll p;
ll a[500005];
struct node
{
	ll sum;
	int l,r;
	int len()
	{
		return (r-l+1);
	}
	ll tag1,tag2;//1:乘法,2:加法 
};
node t[2000005];
void pushup(int id)
{
	t[id].sum=(((t[id*2].sum*1ll%p+t[id*2+1].sum*1ll%p))*1ll)%p;
	return;
} 
void build(int id,int l,int r)
{
	t[id].l=l;
	t[id].r=r;
	t[id].tag1=1;
	t[id].tag2=0;
	if(l==r)
	{
		t[id].sum=a[l]%p;
		return;
	}
	int mid=(l+r)/2;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	pushup(id);
}
void savetag1(int id,ll w)
{
	t[id].sum=((1ll*t[id].sum*1ll*w)%p)%p;
	t[id].tag1=(1ll*t[id].tag1*w)%p;
	t[id].tag2=(1ll*t[id].tag2*w)%p;
}
void savetag2(int id,ll w)
{
	t[id].sum=(t[id].sum%p+t[id].len()*(ll)w*1ll%p)%p;
	t[id].tag2=1ll*(t[id].tag2+w)%p;
}
void pushdown(int id)
{
	if(t[id].tag1!=0)
	{
		savetag1(id*2,1ll*t[id].tag1);
		savetag1(id*2+1,1ll*t[id].tag1);
		t[id].tag1=1;
	}
	if(t[id].tag2!=0)
	{
		savetag2(id*2,t[id].tag2%p);
		savetag2(id*2+1,t[id].tag2%p);
		t[id].tag2=0;
	}
	return;
}
void update1(int id,int l,int r,int x,int y,ll w)//乘法 
{
	if(x<=l&&r<=y)
	{
		savetag1(id,w%p);
		return;
	}
	pushdown(id);
	int mid=(l+r)/2;
	if(mid>=x)
	{
		update1(id*2,l,mid,x,y,w);
	}
	if(mid<y)
	{
		update1(id*2+1,mid+1,r,x,y,w);
	}
	pushup(id);
}
void update2(int id,int l,int r,int x,int y,ll w)
{
	if(x<=l&&r<=y)
	{
		savetag2(id,w);
		return;
	}
	pushdown(id);
	int mid=(l+r)/2;
	if(mid>=x)
	{
		update2(id*2,l,mid,x,y,w);
	}
	if(mid<y)
	{
		update2(id*2+1,mid+1,r,x,y,w);
	}
	pushup(id);
}
ll query(int id,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)
	{
		return t[id].sum%p;
	}
	pushdown(id);
	int mid=(l+r)/2;
	ll tot=0;
	if(mid>=x)
	{
		tot=(tot+query(id*2,l,mid,x,y)*1ll)%p;
	}
	if(y>mid)
	{
		tot=(tot+query(id*2+1,mid+1,r,x,y)*1ll)%p;
	}
	return tot;
}
int main()
{
	cin.tie(0)->ios::sync_with_stdio(0);
//	freopen("xds.in","r",stdin);
//	freopen("xds.out","w",stdout);
	cin>>n>>m>>p;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build(1,1,n);
	int op;
	ll t,g,c;
	while(m--)
	{
		cin>>op;
		if(op==1)
		{
			cin>>t>>g>>c;
			update1(1,1,n,t,g,c);
		}
		if(op==2)
		{
			cin>>t>>g>>c;
			update2(1,1,n,t,g,c);
		}
		if(op==3)
		{
			cin>>t>>g;
            ll ans=(query(1,1,n,t,g)*1ll)%p;
			cout<<((ans*1ll)%p+p)%p<<'\n'; 
		}
	}
	return 0;
}
2024/10/15 21:47
加载中...