动态开点线段树80pts求助
  • 板块P2781 传教
  • 楼主AutiFancers
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/14 16:03
  • 上次更新2023/11/14 16:28:45
查看原帖
动态开点线段树80pts求助
558324
AutiFancers楼主2023/11/14 16:03

测评记录

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;

const int N=30010;
int n,m;

struct node {
	ll val,lazy;
	node *lc,*rc;
	node() {
		val=0,lazy=0,lc=rc=NULL;
	}
	void pushup() {
		val=0;
		if(lc) val+=lc->val;
		if(rc) val+=rc->val;
	}
	void pushdown(int l,int r) {
		if(!lc) lc=new node;
		if(!rc) rc=new node;
		
		int mid=l+r>>1;
		lc->val+=(mid-l+1)*lazy,lc->lazy+=lazy;
		rc->val+=(r-mid)*lazy,rc->lazy+=lazy;
		lazy=0;
	}
	
}*root=new node;

void modify(node* cur,int l,int r,int ql,int qr,int k) {
	if(ql<=l && qr>=r) {
		cur->val+=(r-l+1)*k;
		cur->lazy+=k;
	}
	else {
		cur->pushdown(l,r);
		int mid=l+r>>1;
		if(ql<=mid) modify(cur->lc,l,mid,ql,qr,k);
		if(qr>mid) modify(cur->rc,mid+1,r,ql,qr,k);
		cur->pushup();
	}
} 

ll query(node* cur,int l,int r,int ql,int qr) {
	if(ql<=l && qr>=r) return cur->val;
	int mid=l+r>>1;
	ll ans=0;
	cur->pushdown(l,r);
	if(ql<=mid) ans+=query(cur->lc,l,mid,ql,qr);
	if(qr>mid) ans+=query(cur->rc,mid+1,r,ql,qr);
	return ans;
}

int main() {
	scanf("%d%d",&n,&m);
	while(m--) {
		int op,l,r,k;
		scanf("%d%d%d",&op,&l,&r);
		if(op==1) {
			scanf("%d",&k);
			modify(root,1,n,l,r,k);
		}
		else {
			printf("%lld\n",query(root,1,n,l,r));
		}
	}
	
	return 0;
}
2023/11/14 16:03
加载中...