求助线段树2,样例卡死了
查看原帖
求助线段树2,样例卡死了
158878
B1ade_楼主2022/2/12 11:18

RTRT

#define ll long long 
#include<bits/stdc++.h>
using namespace std;
ll a[40001],pt[40001],mp[40001],data[10001];
//a存储线段树,pt存储加法标记,mp存储乘法标记,data存储原数组
ll MOD,n,m;
ll ls(ll x) {return x*2;}         //左儿子快捷方式 
ll rs(ll x) {return x*2+1;}       //右儿子快捷方式 
void pushup(ll x)
{a[x]=(a[ls(x)]+a[rs(x)])%MOD;}       //更新 
void build(ll x,ll l,ll r)                     //构建 
{
	if (l==r) {a[x]=data[l];return;}            //叶子节点 
	ll mid=(l+r)>>1;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);                        //左右儿子构造 
	pushup(x); 
}
void plus_put_tag(ll T,ll x,ll y,ll k)    //加法更改 
{
	pt[T]=(pt[T]+k)%MOD;
	a[T]=(a[T]+(y-x+1)*k)%MOD;
}

void multiply_put_tag(ll T,ll k)
{
	pt[T]=pt[T]*k%MOD;
	mp[T]=mp[T]*k%MOD;
	a[T]=a[T]*k%MOD;
}

void add(ll T,ll al,ll ar,ll x,ll y,ll k)  //区间加操作,T表示当前节点,al ar表示要加的范围,x y表示当前节点的范围,k表示加的数 
{
	if (al<=x&&y<=ar)
	{
		plus_put_tag(T,x,y,k);
		return;
	}
	if (x<al&&y>ar) return;
	ll mid=(x+y)>>1;
	add(ls(T),al,ar,x,mid,k);
	add(rs(T),al,ar,mid+1,y,k);
	pushup(T);
}

void multiply(ll T,ll al,ll ar,ll x,ll y,ll k)  //区间乘法,变量同上
{
	if (al<=x&&y<=ar)
	{
		multiply_put_tag(T,k);
		return;
	}
	if (x<al&&y>ar) return;
	ll mid=(x+y)>>1;
	multiply(ls(T),al,ar,x,mid,k);
	multiply(rs(T),al,ar,mid+1,y,k);
	pushup(T);
}

void pushdown (ll T,ll x,ll y)    //标记下传 
{
	if (x==y) return;
	ll mid=(x+y)>>1;
	if (mp[T])
	{
		multiply_put_tag(ls(T),mp[T]);
		multiply_put_tag(rs(T),mp[T]);
		mp[T]=0;
	}
	if (pt[T])
	{
		plus_put_tag(ls(T),x,mid,pt[T]);
		plus_put_tag(rs(T),mid+1,y,pt[T]);
		pt[T]=0;
	}
}

ll query(ll T,ll al,ll ar,ll x,ll y)//区间查询,变量同上
{
	if (x<al&&y>ar) return 0;
	if (al<=x&&y<=ar)
	{
		return a[T]%MOD;
	}
	pushdown(T,x,y);
	ll ans=0,mid=(x+y)>>1;
	ans=(ans+query(ls(T),al,ar,x,mid))%MOD;
	ans=(ans+query(rs(T),al,ar,mid+1,y))%MOD;
	return ans%MOD;
}

int main()
{
	cin>>n>>m>>MOD;
	for (int i=1;i<=n;++i) cin>>data[i];
	build(1,1,n);
	for (int i=1;i<=m;++i)
	{
		ll op,x,y,k;cin>>op>>x>>y;
		if (op==1)
		{
			cin>>k;
			multiply(1,x,y,1,n,k);
		}
		if (op==2)
		{
			cin>>k;
			add(1,x,y,1,n,k);
		}
		if (op==3)
		{
			cout<<query(1,x,y,1,n);
		}
	}
	return 0;
}
2022/2/12 11:18
加载中...