求助线段树码风
  • 板块灌水区
  • 楼主yinbe2
  • 当前回复12
  • 已保存回复12
  • 发布时间2024/7/20 21:25
  • 上次更新2024/7/20 22:51:03
查看原帖
求助线段树码风
1285691
yinbe2楼主2024/7/20 21:25

是这样好:

#include<iostream>
using namespace std;
struct tree
{
	int l,r;
	long long sum,add;
	#define l(x) t[x].l
	#define r(x) t[x].r
	#define sum(x) t[x].sum
	#define add(x) t[x].add
}t[400005];
int n,m,a[100005];
void build(int p,int l,int r)
{
	l(p)=l,r(p)=r;
	if(l==r)
	{
		sum(p)=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	sum(p)=sum(p*2)+sum(p*2+1);
	return;
}
void spread(int p)
{
	if(add(p))
	{
		sum(p*2)+=add(p)*(r(p*2)-l(p*2)+1);
		sum(p*2+1)+=add(p)*(r(p*2+1)-l(p*2+1)+1);
		add(p*2)+=add(p);
		add(p*2+1)+=add(p);
		add(p)=0;
	}
	return;
}
void change(int p,int l,int r,int d)
{
	if(l<=l(p)&&r>=r(p))
	{
		sum(p)+=(long long)(d)*(r(p)-l(p)+1);
		add(p)+=d;
		return;
	}
	spread(p);
	int mid=(l(p)+r(p))>>1;
	if(l<=mid)change(p*2,l,r,d);
	if(r>mid)change(p*2+1,l,r,d);
	sum(p)=sum(p*2)+sum(p*2+1);
	return;
}
long long ask(int p,int l,int r)
{
	if(l<=l(p)&&r>=r(p))
	{
		return sum(p);
	}
	spread(p);
	int mid=(l(p)+r(p))>>1;
	long long ans=0;
	if(l<=mid)ans+=ask(p*2,l,r);
	if(r>mid)ans+=ask(p*2+1,l,r);
	return ans;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	build(1,1,n);
	while(m--)
	{
		int flag,l,r,d;
		scanf("%d",&flag);
		if(flag==1)
		{
			scanf("%d%d%d",&l,&r,&d);
			change(1,l,r,d);
		}
		else if(flag==2)
		{
			scanf("%d%d",&l,&r);
			printf("%lld\n",ask(1,l,r));
		}
	}
	return 0;
}

还是这样好:

#include<iostream>
using namespace std;
int n,T;
long long mod,a[100005];
struct tree
{
	int l,r;
	long long v,add,times;
}c[400005];
void build(int p,int l,int r)
{
	c[p].l=l,c[p].r=r;
	if(l==r)
	{
		c[p].v=a[l]%mod;
		c[p].times=1;
		return;
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	c[p].times=1;
	c[p].v=c[p*2].v+c[p*2+1].v;
	c[p].v%=mod;
	return; 
}
void spread(int p)
{
	c[p*2].v=(c[p*2].v*c[p].times+c[p].add*(c[p*2].r-c[p*2].l+1))%mod;
	c[p*2+1].v=(c[p*2+1].v*c[p].times+c[p].add*(c[p*2+1].r-c[p*2+1].l+1))%mod;
	c[p*2].times=c[p*2].times*c[p].times%mod;
	c[p*2+1].times=c[p*2+1].times*c[p].times%mod;
	c[p*2].add=(c[p*2].add*c[p].times+c[p].add)%mod;
	c[p*2+1].add=(c[p*2+1].add*c[p].times+c[p].add)%mod;
	c[p].add=0;
	c[p].times=1;
	return;
}
void change(int p,int l,int r,long long d,int op)
{
	if(l<=c[p].l&&r>=c[p].r)
	{
		if(op==1)
		{
			c[p].v=c[p].v*d%mod;
			c[p].times=c[p].times*d%mod;
			c[p].add=c[p].add*p%mod;
		}
		else
		{
			c[p].v=(c[p].v+d)%mod;
			c[p].add=(c[p].add+d)%mod;
		}
		return;
	}
	spread(p);
	int mid=(c[p].l+c[p].r)>>1;
	if(l<=mid)change(p*2,l,r,d,op);
	if(r>mid)change(p*2+1,l,r,d,op);
	c[p].v=(c[p*2].v+c[p*2+1].v)%mod;
	return;
}
long long ask(int p,int l,int r)
{
	if(l<=c[p].l&&r>=c[p].r)
	{
		return c[p].v; 
	}
	spread(p);
	int mid=(c[p].l+c[p].r)>>1;
	long long sum=0;
	if(l<=mid)sum+=ask(p*2,l,r);
	if(r>mid)sum+=ask(p*2+1,l,r);
	sum%=mod;
	return sum;
}
int main()
{
	scanf("%d%d%lld",&n,&T,&mod);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	build(1,1,n);
	while(T--)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int l,r;
			long long k;
			scanf("%d%d%lld",&l,&r,&k);
			change(1,l,r,k,1);
		}
		else if(op==2)
		{
			int l,r;
			long long k;
			scanf("%d%d%lld",&l,&r,&k);
			change(1,l,r,k,2);
		}
		else
		{
			int l,r;
			scanf("%d%d",&l,&r);
			printf("%lld\n",ask(1,l,r));
		}
	}
	return 0;
}

即要不要#define

2024/7/20 21:25
加载中...