样例没过,zhx版的线段树
查看原帖
样例没过,zhx版的线段树
535356
Forgetful楼主2023/10/11 17:05
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define root 1,n,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
const int N=1e6+10;
int n,k,a[N],q;
struct node
{
	int l,r;
	int add=0,sum,mul=1;
	void init(int l_,int r_)
	{
		l=l_;
		r=r_;
		add=0;
		mul=1;
		sum=a[l];
	}
}z[N];
void color(int rt,int v,int k)
{
	z[rt].mul*=k;
	z[rt].sum*=k;
	z[rt].add*=k;
	z[rt].add+=v;
	z[rt].sum+=(z[rt].r-z[rt].l+1)*v;
}
void pushdown(int rt)
{
	if(z[rt].mul!=1||z[rt].add!=0)
	{
		color(rt<<1,z[rt].add,z[rt].mul);
		color(rt<<1|1,z[rt].add,z[rt].mul);
		z[rt].mul=1;
		z[rt].add=0;
	}

}
node operator+(const node &l,const node &r)
{
	node p;
	p.l=l.l;
	p.r=r.r;
	p.sum=l.sum+r.sum;
	p.add=0;
	p.mul=1;
	return p;
}

void update(int rt)
{
	z[rt]=z[rt<<1]+z[rt<<1|1];
}
void build(int l,int r,int rt)
{
	if(l==r)
	{
		z[rt].init(l,r);
		return;
	}
	int m=l+r>>1;
	build(lson);
	build(rson);
	update(rt);
}
void modify(int l,int r,int rt,int nowl,int nowr,int v,int k)
{
	if(nowl<=l&&r<=nowr)
	{
		color(rt,v,k);
		return;
	}
	pushdown(rt);
	int m=l+r>>1;
	if(nowl<=m)modify(lson,nowl,nowr,v,k);
	if(nowr>m) modify(rson,nowl,nowr,v,k);
	update(rt);
}
node query(int l,int r,int rt,int nowl,int nowr)
{
	if(nowl<=l&&r<=nowr)
	{
		return z[rt];
	}
	pushdown(rt);
	int m=l+r>>1;
	if(nowl<=m)
	{
		if(nowr>m)return query(lson,nowl,nowr)+query(rson,nowl,nowr);
		else return query(lson,nowl,nowr);
	}
	else return query(rson,nowl,nowr);
}
signed main()
{
	cin>>n>>k>>q;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build(1,n,1);
	for(int i=1;i<=k;i++)
	{
		int op;
		cin>>op;
		if(op==1)
		{
			int l,r,v;
			cin>>l>>r>>v;
			modify(root,l,r,0,v);
		}
		if(op==2)
		{
			int l,r,v;
			scanf("%d%d%d",&l,&r,&v);
			modify(root,l,r,v,1);
		}
		if(op==3)
		{
			int l,r;
			cin>>l>>r;
			cout<<query(root,l,r).sum%q<<endl;
		}
	}
	
	return 0;
}
2023/10/11 17:05
加载中...