zkw线段树RE 0分求条(本地是对的)
查看原帖
zkw线段树RE 0分求条(本地是对的)
1418281
nauyng楼主2024/11/28 12:09
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,m,l,r,k,x,a[100005],f[400005],g[400005];
int build()
{
	for(m=1;m<=n;m<<=1);
	for(int i=1;i<=n;i++)
		f[i+m]=a[i];
	for(int i=m-1;i>0;i--)
		f[i]=f[i*2]+f[i*2+1];
}
void change(int l,int r,int k)
{
	int nx=1,lx=0,rx=0;
	l=l-1+m,r=r+1+m;
	while((l>>1)!=(r>>1))
	{
		f[l]+=lx*k;
		f[r]+=rx*k;
		if(~l&1)
		{
			f[l+1]+=k*nx;
			g[l+1]+=k;
			lx+=nx;
		}
		if(r&1)
		{
			f[r-1]+=k*nx;
			g[l+1]+=k; 
			rx+=nx; 
		}
		l>>=1;
		r>>=1;
		nx<<=1;
	}
	for(;l&&r;l>>=1,r>>=1)
	{
		f[l]+=lx*k; 
		f[r]+=rx*k;
	}
}
int query(int l,int r)
{
	int sum=0,lx=0,rx=0,nx=1;
	l=l-1+m,r=r+1+m;
	while((l>>1)!=(r>>1))
	{
		if(g[l])
			sum+=g[l]*lx;
		if(g[r])
			sum+=g[r]*rx;
		if(~l&1)
		{
			sum+=f[l+1];
			lx+=nx;
		}
		if(r&1)
		{
			sum+=f[r-1];
			rx+=nx;
		}
		l>>=1;
		r>>=1;
		nx<<=1;
	}
	for(;l&&r;l>>=1,r>>=1)
	{
		sum+=lx*g[l]; 
		sum+=rx*g[r];
	}
	return sum;
}
signed main()
{
	scanf("%lld%lld",&n,&q);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	build();
	for(int i=1;i<=q;i++)
	{
		int x,l,r;
		scanf("%lld%lld%lld",&x,&l,&r);
		if(x==1)
		{
			int k;
			scanf("%lld",&k);
			change(l,r,k);
		}
		if(x==2)
			printf("%lld\n",query(l,r));
	}
	return 0;
}
2024/11/28 12:09
加载中...