我不会线段树……
查看原帖
我不会线段树……
769863
_Lyk_def楼主2023/7/2 16:18

维护首项和公差

码风规整,逻辑(并不)严密,封装(还算)合理

#include<bits/stdc++.h>
using namespace std;
const int Maxn=1e6;
typedef long long ll;
ll a[Maxn];
ll tree[Maxn],tagk[Maxn],tagd[Maxn];
inline int ls(int x){ return x<<1; }
inline int rs(int x){ return x<<1|1; }
void build(int p,int l,int r){
	if(l==r){
		tree[p]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
}
void lazy_tag(int p,ll k,ll d,bool ison){
	if(ison){ tree[p]+=k; return; }
	tagk[p]+=k;
	tagd[p]+=d;
}
void push_down(int p,int l,int r){
	int mid=(l+r)>>1;
	lazy_tag(ls(p),tagk[p],tagd[p],l==mid);
	lazy_tag(rs(p),tagk[p]+tagd[p]*(mid-l+1),tagd[p],mid+1==r);
	tagk[p]=tagd[p]=0;
}
int nl,nr,nq;
void update(int p,int l,int r,ll K,ll D){
	if(nl<=l&&r<=nr){
		lazy_tag(p,K,D,l==r);
		return;
	}
	push_down(p,l,r);
	int mid=(l+r)>>1;
	if(nl<=mid) update(ls(p),l,mid,K,D);
	if(nr> mid) update(rs(p),mid+1,r,K+(mid-l+1)*D,D);
}
ll query(int p,int l,int r){
	if(l==r) return tree[p];
	push_down(p,l,r);
	int mid=(l+r)>>1;
	if(nq<=mid)	return query(ls(p),l,mid);
	else		return query(rs(p),mid+1,r);
}
int n,m,opt;
ll K,D;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	build(1,1,n);
	while(m--){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%lld%lld",&nl,&nr,&K,&D);
			update(1,1,n,K,D);
		}
		if(opt==2){
			scanf("%d",&nq);
			printf("%lld\n",query(1,1,n));
		}
	}
	return 0;
}
2023/7/2 16:18
加载中...