求助,线段树,search数组有问题
查看原帖
求助,线段树,search数组有问题
553772
GLESENA楼主2023/8/3 19:40

代码 :

#include<bits/stdc++.h>
using namespace std;
#define lc i<<1
#define rc i<<1|1
#define mid (l+r)/2
int inPut[100000+1];
struct tree{
	int l,r,sum,lazytag;
}t[100000001];
void push_down(int i)
{
	t[lc].lazytag+=t[i].lazytag;
	t[rc].lazytag+=t[i].lazytag;
	t[lc].sum+=t[i].lazytag*(t[lc].r-t[lc].l+1);
	t[rc].sum+=t[i].lazytag*(t[rc].r-t[rc].l+1);
	t[i].lazytag=0;
}
void build(int i,int l,int r)
{
	t[i].l=l;t[i].r=r;
	if(l==r)
	{
		t[i].sum=inPut[l];
		return ;
	}
	build(lc,l,mid);
	build(rc,mid+1,r);
	t[i].sum=t[lc].sum+t[rc].sum;
}
int search(int i,int l,int r)
{
	//cout<<t[i].l<<" "<<t[i].r<<' '<<l<<' '<<r<<'\n';
	if(l<=t[i].l&&r>=t[i].r)
	{
		return t[i].sum+t[i].lazytag*(t[i].r-t[i].l+1);
	}
	if(l>=t[i].r||r<=t[i].l)
	{
		return 0;
	}
	int rtrn=0;
	push_down(i);
	if(l<=t[lc].r)
	{
		rtrn+=search(lc,l,r);
	}
	if(r>=t[rc].l)
	{
		rtrn+=search(rc,l,r);
	}
	return rtrn;
}
void add(int i,int l,int r,int k)
{
	if(l<=t[i].l&&r>=t[i].r)
	{
		t[i].lazytag=k;
		t[i].sum+=k*(t[i].r-t[i].l+1);
		return ;
	}
	push_down(i);
	if(l<=t[lc].r)
	{
		add(lc,l,r,k);
	}
	if(r>=t[rc].l)
	{
		add(rc,l,r,k);
	}
	t[i].sum=t[lc].sum+t[rc].sum;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&inPut[i]);
	}
	build(1,1,n);
	int op,x,y,k;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d%d",&x,&y,&k);
			add(1,x,y,k);
		}
		if(op==2)
		{
			scanf("%d%d",&x,&y);
			cout<<search(1,x,y)<<endl;
		}
	}
	return 0;
}

求区间和时,位于区间边缘的数如果需要push_back到t[i].l==t[i].r,就无法被计算。

如 输入

8 1
1 1 1 1 1 1 1 1
2 4 6

输出

2

如下面横线下的3个1都应该被计算,结果应该为1+1+1=3。 但第4个1没有被计算,只计算了第5和第6个1,结果为输出了2。

      _____
1 1 1 1 1 1 1 1
1 1 1 1|1 1 1 1
1 1|1 1|1 1|1 1
1|1|1|1|1|1|1|1
1 2 3 4 5 6 7 8 

也就是说,search函数正确无法查询到长度为1的区间的值。

蒟蒻求助。

2023/8/3 19:40
加载中...