玄关求条(马蜂良好,有注释)
查看原帖
玄关求条(马蜂良好,有注释)
785713
yzjznbQWQ楼主2024/10/23 21:33

rt

#include<bits/stdc++.h>
#define ll long long

using namespace std;

const int N = 1e5+5;

inline int read();

int w[N<<1],a[N],lzy_add[N<<1];

inline void pushup(int u) {w[u]=w[u<<1]+w[u<<1|1];} 

inline bool InRange(int L,int R,int l,int r) {return (L>=l)&&(R<=r);}//判断该区间是否是目标区间的子集 

inline bool OutofRange(int L,int R,int l,int r) {return (L>r)||(R<l);}//判断该区间是否和目标区间有交集 

inline void MakeTag_add(int u,int len,int v) {lzy_add[u]+=v;w[u]+=len*v;}//打懒标记 

inline void pushdown(int u,int l,int r)//下放标记 
{
	int mid=(l+r)>>1;
	MakeTag_add(u<<1,mid-l+1,lzy_add[u]);
	MakeTag_add(u<<1|1,r-mid,lzy_add[u]);
	lzy_add[u]=0;
}

inline void build(int u,int l,int r)//建树 
{
	if(l==r)
	{
		w[u]=a[l];
		return;
	}
	
	int mid=(l+r)>>1; 
	build(u<<1,l,mid);
	build(u<<1|1,mid+1,r);
	
	pushup(u);
}

inline int query_one(int u,int L,int R,int p)//单点查询(与这题无关 
{
	if(L==R) return w[u];
	
	int mid=(L+R)>>1;
	if(mid>=p) query_one(u<<1,L,mid,p);
	else query_one(u<<1|1,mid+1,R,p);
}

inline int update_one(int u,int L,int R,int p,int v)//单点修改(与这题无关 
{
	if(L==R) w[u]=v;
	else
	{
		int mid=(L+R)>>1;
		if(mid>=p) update_one(u<<1,L,mid,p,v);
		else update_one(u<<1|1,mid+1,R,p,v);
		
		pushup(u);
	}
}

inline int query(int u,int L,int R,int l,int r)//区间求和 
{
	if(InRange(L,R,l,r)) return w[u];
	
	else if(!OutofRange(L,R,l,r))
	{
		int mid=(L+R)>>1;
		pushdown(u,L,R);
		return query(u<<1,L,mid,l,r)+query(u<<1|1,mid+1,R,l,r);
	}
	
	else return 0;
}

inline void update_add(int u,int L,int R,int l,int r,int v)//区间加 
{
	if(InRange(L,R,l,r)) MakeTag_add(u,R-L+1,v);
	else if(!OutofRange(L,R,l,r))
	{
		int mid=(L+R)>>1;
		
		pushdown(u,L,R);
		
		update_add(u<<1,L,mid,l,r,v);
		update_add(u<<1|1,mid+1,R,l,r,v);
		
		pushup(u);
	}
}

int main(){
	int n=read(),q=read();//mod=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	while(q--)
	{
		int opt=read();
		if(opt==1) update_add(1,1,n,read(),read(),read());
		else if(opt==2) printf("%d\n",query(1,1,n,read(),read()));
	}
	return 0;
}

inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-') f=0;
		c=getchar();
	}
	while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48,c=getchar();
	return f?x:(~(x-1));
}

/*
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
*/
2024/10/23 21:33
加载中...