改版线段树,全WA
  • 板块学术版
  • 楼主Eydte
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/5/14 12:03
  • 上次更新2023/10/28 01:29:31
查看原帖
改版线段树,全WA
359057
Eydte楼主2022/5/14 12:03

题目链接

题目大意:

在原来的 区间加区间求和 基础上,添加了 区间乘区间求每个数的平方的和

#include <bits/stdc++.h>
#define ll long long
#define maxn 100005
#define mod 998244353
#define reg register int
#define ivoid inline void

int n,q,opt,x,y,z,a[maxn];

struct xds
{
	int l,r;
	ll sum1,sum2;
	int laz1,laz2;
}t[4*maxn];

ivoid down(int p)
{
	t[p*2].laz1+= t[p].laz1; t[p*2+1].laz1+= t[p].laz1;
	t[p*2].laz2+= t[p].laz2; t[p*2+1].laz2+= t[p].laz2;
	t[p].laz1= 0; t[p].laz2= 1;
	return;
}

int pd(int p)
{
	if(t[p].laz1!=0 || t[p].laz2!=1)
		return 1;
	return 0;
}

ivoid build(int p,int l,int r)
{
	t[p].l=l; t[p].r=r; t[p].laz2=1;
	if(l==r)  
	{
		t[p].sum1=a[l]; t[p].sum2=a[l]*a[l]%mod;
		return;
	}
	int mid=(l+r)/2;
	build(p*2,l,mid); build(p*2+1,mid+1,r);
	t[p].sum1=(t[p*2].sum1 + t[p*2+1].sum1)%mod;
	t[p].sum2=(t[p*2].sum2 + t[p*2+1].sum2)%mod;
	return;
}

ivoid plu(int p,int x,int y,int z)//区间加 
{
	
	if(x<=t[p].l && t[p].r<=y)
	{
		t[p].sum2+= (2*t[p].sum1*z + (t[p].r-t[p].l+1)*z*z)%mod;
		t[p].sum1+= z*(t[p].r - t[p].l +1);
		t[p].laz1+= z;
		return;
	}
	
	if(t[p].l<=x && y<=t[p].r && pd(p)==1)
		down(p);
	
	int mid=(t[p].l + t[p].r)/2;
	if(x<=mid)  plu(p*2,x,y,z);
	if(mid+1<=y)  plu(p*2+1,x,y,z);
	
	t[p].sum1=(t[p*2].sum1 + t[p*2+1].sum1)%mod;
	t[p].sum2=(t[p*2].sum2 + t[p*2+1].sum2)%mod;
	return;
}

ivoid mul(int p,int x,int y,int z)//区间乘
{
	if(x<=t[p].l && t[p].r<=y)
	{
		t[p].sum2= ((t[p].sum2*z %mod) *z)%mod;
		t[p].sum1= t[p].sum1*z %mod;
		t[p].laz1*= z;
		t[p].laz2*= z;
		return;
	}
	
	if(t[p].l<=x && y<=t[p].r && pd(p)==1)
		down(p);
	
	int mid=(t[p].l + t[p].r)/2;
	if(x<=mid)  mul(p*2,x,y,z);
	if(mid+1<=y) mul(p*2+1,x,y,z);
	
	t[p].sum1=(t[p*2].sum1 + t[p*2+1].sum1)%mod;
	t[p].sum2=(t[p*2].sum2 + t[p*2+1].sum2)%mod;
	return;
} 

ll query1(int p,int x,int y)//数值和
{
	if(x<=t[p].l && t[p].r<=y)
		return t[p].sum1;
	
	if(t[p].l<=x && y<=t[p].r && pd(p)==1)
		down(p);
		
	ll ans=0;
	
	int mid=(t[p].l + t[p].r)/2;
	if(x<=mid)  ans= (ans+ query1(p*2,x,y)) %mod;
	if(mid+1<=y)  ans= (ans+ query1(p*2+1,x,y)) %mod;
	return ans;
}

ll query2(int p,int x,int y)//平方和
{
	if(x<=t[p].l && t[p].r<=y)
		return t[p].sum2;
	
	if(t[p].l<=x && y<=t[p].r && pd(p)==1)
		down(p);
	
	ll ans=0;
	
	int mid=(t[p].l + t[p].r)/2;
	if(x<=mid)  ans= (ans+ query2(p*2,x,y)) %mod;
	if(mid+1<=y)  ans= (ans+ query2(p*2+1,x,y)) %mod;
	return ans;
}

int main()
{
	scanf("%d %d",&n,&q);
	for(reg i=1;i<=n;i++)
		scanf("%d",&a[i]);
	build(1,1,n);
	t[0].laz2= 1;
	while(q>0)
	{
		q--;
		scanf("%d",&opt);
		scanf("%d %d",&x,&y);
		switch(opt)
		{
			case 1:
				scanf("%d",&z);
				plu(1,x,y,z);//区间加 
				break;
			case 2:
				scanf("%d",&z);
				mul(1,x,y,z);//区间乘 
				break;
			case 3:
				printf("%lld\n",query1(1,x,y));//数值和
				break;
			case 4:
				printf("%lld\n",query2(1,x,y));//平方和 
				break;
		}
	}
}
```c++
2022/5/14 12:03
加载中...