HELP TREE!
查看原帖
HELP TREE!
519092
阿宁已被领养楼主2022/7/28 10:32

我就知道我的线段树一定会超时的。。。。qwq

最后三个点T了,到底哪些函数是没必要或者是可以优化的啊qwq

#include <iostream>
#include <cstdio>
using namespace std;
long long n,m,a[1000000],t,x,y,k;
struct gs
{
	long long l,r,num,j;
}shu[1000000];
void build(long long g,long long l,long long r)
{
	shu[g].l=l;
	shu[g].r=r;
	if(l==r)
	{
		shu[g].num=a[l];
		return ;
	}
	long long mid=(l+r)/2;
	build(g*2,l,mid);
	build(g*2+1,mid+1,r);
	shu[g].num=shu[g*2].num+shu[g*2+1].num;
	return ;
}
void sh(long long g,long long num)//向上更新 区间和 
{
	if(g==0) return ;
	shu[g].num+=num;
	sh(g/2,num);
}
void cd(long long g)//向下传递要加的标记 
{
	if(shu[g].l==shu[g].r) {shu[g].num+=shu[g].j;sh(g/2,shu[g].j);shu[g].j=0;return ;}
	shu[g*2].j+=shu[g].j;
	shu[g*2+1].j+=shu[g].j;
	shu[g].j=0;
	cd(g*2);
	cd(g*2+1);
}
void jia(long long g,long long l,long long r,long long num)//区间加 
{
	if(shu[g].l>r||shu[g].r<l) return ;
	if(shu[g].l>=l&&shu[g].r<=r) {shu[g].j+=num;cd(g);return ;}
	long long mid=(shu[g].l+shu[g].r)/2;
	if(l<=mid) jia(g*2,l,r,num);
	if(r>mid) jia(g*2+1,l,r,num);
	return ;
}
long long count(long long g,long long l,long long r,long long ans)//输出区间的值 
{
	if(shu[g].l>r||shu[g].r<l) return 0;
	if(shu[g].l>=l&&shu[g].r<=r) {ans+=shu[g].num;/*cout<<endl<<g<<endl;*/return ans;}
	long long mid=(shu[g].l+shu[g].r)/2;
	if(l<=mid) ans+=count(g*2,l,r,0);
	if(r>mid) ans+=count(g*2+1,l,r,0);
	return ans;
}
int main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		scanf("%lld",&t);
		if(t==1)
		{
			scanf("%lld%lld%lld",&x,&y,&k);
			jia(1,x,y,k);
		}
		if(t==2)
		{
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",count(1,x,y,0));
		}
	}
	return 0;
}
2022/7/28 10:32
加载中...