30pts求助
查看原帖
30pts求助
561297
AbelTomato楼主2022/7/21 11:56

看了一圈讨论区30分的,感觉错的不一样

#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define maxn 100001
#define ll long long
#define ull unsigned long long
#define ls k<<1
#define rs k<<1|1
using namespace std;
int n,m,p;
int a[maxn];
int op,x,y,d;
struct node
{
	int l,r;
	ll s,lz1,lz2;
}t[maxn<<2];
void build(int l,int r,int k)
{
	t[k].l=l;
	t[k].r=r;
	t[k].lz2=1;
	if(l==r)
	{
		t[k].s=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls);
	build(mid+1,r,rs);
	t[k].s=t[ls].s+t[rs].s;
}
void pushdown(int k)
{
	t[ls].s=(t[ls].s*t[k].lz2+t[k].lz1*(t[ls].r-t[ls].l+1))%p;
	t[rs].s=(t[rs].s*t[k].lz2+t[k].lz1*(t[rs].r-t[rs].l+1))%p;
	t[ls].lz2=(t[ls].lz2*t[k].lz2)%p;
	t[rs].lz2=(t[rs].lz2*t[k].lz2)%p;
	t[ls].lz1=(t[ls].lz1+t[k].lz1)%p;
	t[rs].lz1=(t[rs].lz1+t[k].lz1)%p;
	t[k].lz1=0;
	t[k].lz2=1;
	return;
}
void pro(int x,int y,int k,int d)
{
	if(t[k].l>=x&&t[k].r<=y)
	{
		t[k].s=(t[k].s*d)%p;
		t[k].lz2=(t[k].lz2*d)%p;
		t[k].lz1=(t[k].lz1*d)%p;
		return;
	}
	pushdown(k);
	int mid=(t[k].l+t[k].r)>>1;
	if(mid>=x)
	{
		pro(x,y,ls,d);
	}
	if(mid<y)
	{
		pro(x,y,rs,d);
	}
	t[k].s=(t[ls].s+t[rs].s)%p;
}
void sum(int x,int y,int k,int d)
{
	if(t[k].l>=x&&t[k].r<=y)
	{
		t[k].s=(t[k].s+d*(t[k].r-t[k].l+1))%p;
		t[k].lz1=(t[k].lz1+d)%p;
		return;
	}
	pushdown(k);
	int mid=(t[k].l+t[k].r)>>1;
	if(mid>=x)
	{
		sum(x,y,ls,d);
	}
	if(mid<y)
	{
		sum(x,y,rs,d);
	}
	t[k].s=(t[ls].s+t[rs].s)%p;
}
ll ask(int x,int y,int k)
{
	if(t[k].l>=x&&t[k].r<=y)
	{
		return t[k].s;
	}
	pushdown(k);
	int mid=(t[k].l+t[k].r)>>1;
	ll ans=0;
	if(mid>=x)
	{
		ans=(ans+ask(x,y,ls));
	}
	if(mid<y)
	{
		ans=(ans+ask(x,y,rs));
	}
	return ans%p;
}
int main()
{
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	cin>>n>>m>>p;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build(1,n,1);
	for(int i=1;i<=m;i++)
	{
		cin>>op>>x>>y;
		if(op==1)
		{
			cin>>d;
			pro(x,y,1,d);
		}
		else if(op==2)
		{
			cin>>d;
			sum(x,y,1,d);
		}
		else if(op==3)
		{
			cout<<ask(x,y,1)%p<<endl;
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}

2022/7/21 11:56
加载中...