社区讨论

关于lazytag

P3373【模板】线段树 2参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@m34j0qm4
此快照首次捕获于
2024/11/05 22:09
去年
此快照最后确认于
2025/11/04 15:16
4 个月前
查看原帖
可以只用加法tag,然后把乘法tag直接处理到加法tag上吗
尝试发现是0pts
代码:
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,q,N,opt,x,y,k,a[100010],sum[400010],add[400010];
ll read()
{
	ll s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+ch-'0';
		ch=getchar();
	}
	return s*w;
}
void write(ll x)
{
	if(x<0)
	{
		putchar('-');
		x=-x;
	}
	if(x<=9)putchar(x+'0');
	else write(x/10),putchar(x%10+'0');
	return ;
}
void build(ll id,ll l,ll r)
{
	ll mid=l+r>>1;
	if(l==r)
	{
		sum[id]=a[l];
		return ;
	}
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	sum[id]=sum[id*2]+sum[id*2+1];
	return ;
}
void psd(ll id,ll l,ll r)
{
	ll mid=l+r>>1;
	add[id*2]=(add[id*2]+add[id])%N;
	sum[id*2]=(sum[id*2]+add[id]*(mid-l+1))%N;
	add[id*2+1]=(add[id*2+1]+add[id])%N;
	sum[id*2+1]=(sum[id*2+1]+add[id]*(r-(mid+1)+1))%N;
	add[id]=0;
	return ; 
}
void ad(ll id,ll l,ll r,ll num)
{
	ll mid=l+r>>1;
	if(l>y||r<x)return;
	if(l>=x&&r<=y)
	{
		add[id]=(add[id]+num)%N;
		sum[id]=(sum[id]+num*(r-l+1))%N;
		return ;
	}
	psd(id,l,r);
	ad(id*2,l,mid,num);
	ad(id*2+1,mid+1,r,num);
	sum[id]=(sum[id*2]+sum[id*2+1])%N;
	return ;
}
void tim(ll id,ll l,ll r,ll num)
{
	ll mid=l+r>>1;
	if(l>y||r<x)return;
	if(l>=x&&r<=y)
	{
		add[id]=(add[id]*num)%N;
		sum[id]=(sum[id]*num)%N;
		return ;
	}
	psd(id,l,r);
	tim(id*2,l,mid,num);
	tim(id*2+1,mid+1,r,num);
	sum[id]=(sum[id*2]+sum[id*2+1])%N;
	return ;
}
ll query(ll id,ll l,ll r)
{
	ll mid=l+r>>1;
	if(l>y||r<x)return 0;
	if(l>=x&&r<=y)return sum[id]%N;
	psd(id,l,r);
	return (query(id*2,l,mid)+query(id*2+1,mid+1,r))%N;
}
int main()
{
	n=read();
	q=read();
	N=read();
	for(int i=1;i<=n;i++)a[i]=read();
	build(1,1,n);
	//for(int i=1;i<=2*n;i++)cout<<sum[i]<<" ";
	for(int i=1;i<=q;i++)
	{
		opt=read();
		x=read();
		y=read();
		if(opt==1)
		{
			k=read();
			tim(1,1,n,k);
		}
		if(opt==2)
		{
			k=read();
			ad(1,1,n,k);
		}
		if(opt==3)
		{
			//cout<<query(1,1,n);
			write(query(1,1,n)%N);
			putchar('\n');
		}
	}
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...