萌新求大佬帮调线段树模板
查看原帖
萌新求大佬帮调线段树模板
203102
Diamiko楼主2021/10/26 19:04

真是不知道怎么回事,样例都过不了,求帮调一下吧

k和b是指这个tag把x转换成kx+b的形式

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct LazyTag
{
	ll k,b;
};
struct SegmentTree
{
	int l,r;
	ll val;
	LazyTag tag;
}t[500005];
int n,m,p,a[100005],o,x,y,k;
void MergeData(int x)
{
	t[x].val=(t[x<<1].val+t[x<<1|1].val)%p;
}
void build(int now,int l,int r)
{
	t[now].l=l,t[now].r=r;
	t[now].tag={1,0};
	if(l==r)
	{
//		cout<<"t["<<now<<"].val=a["<<l<<"]"<<"="<<a[l]<<endl;
		t[now].val=a[l]%p;
		return;
	}
	int mid=(l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	MergeData(now);
}
LazyTag MergeTag(LazyTag x,LazyTag y)
{
	int k1=x.k,k2=y.k,b1=x.b,b2=y.b;
	return {k1*k2,k2*b1+b2};
}
void Apply(int x)
{
	t[x].val=((t[x].val%p*t[x].tag.k%p)%p+(t[x].tag.b%p*(t[x].r-t[x].l+1)%p)%p)%p;
}
void GiveTag(int x,LazyTag tag)
{
	t[x].tag=MergeTag(t[x].tag,tag);
//	cout<<t[x].l<<"->"<<t[x].r<<" be given tag.\n";
	Apply(x);
}
void PushDown(int x)
{
	GiveTag(x<<1,t[x].tag);
	GiveTag(x<<1|1,t[x].tag);
	t[x].tag={1,0};
}
void modify(int now,int l,int r,LazyTag x)
{
	if(t[now].l!=t[now].r)PushDown(now);
	if(t[now].l>=l&&t[now].r<=r)
	{
		GiveTag(now,x);
		return;
	}
	int mid=(t[now].l+t[now].r)>>1;
	if(l<=mid)modify(now<<1,l,r,x);
	if(r>mid)modify(now<<1|1,l,r,x);
	MergeData(now);
}
ll query(int now,int l,int r)
{
	if(t[now].l!=t[now].r) PushDown(now);
	if(t[now].l>=l&&t[now].r<=r)return t[now].val;
	int mid=(t[now].l+t[now].r)>>1;
	ll ans=0;
	if(l<=mid) ans=(ans%p+query(now<<1,l,r)%p)%p;
	if(r>mid) ans=(ans%p+query(now<<1|1,l,r)%p)%p;
	return ans;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>m>>p;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		cin>>o>>x>>y;
		if(o==1)
		{
			cin>>k;
			modify(1,x,y,{k,0});
		}
		else if(o==2)
		{
			cin>>k;
			modify(1,x,y,{1,k});
		}
		else
		{
			cout<<query(1,x,y)%p<<endl;
		}
	}
	return 0;
}
2021/10/26 19:04
加载中...