一个动态开点线段树板子,哪位大佬能为蒟蒻调调?(听闻灌水大佬多)
  • 板块灌水区
  • 楼主末然Ender
  • 当前回复21
  • 已保存回复21
  • 发布时间2023/8/16 10:35
  • 上次更新2023/11/3 03:27:02
查看原帖
一个动态开点线段树板子,哪位大佬能为蒟蒻调调?(听闻灌水大佬多)
339728
末然Ender楼主2023/8/16 10:35

rt

//试作动态开点线段树 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+10;
const int inf=0x3f3f3f3f;
struct node{ 
    int lc,rc;//表示该节点所的左右儿子 
    ll val/*所存的值*/;
}t[N<<2]; 
int a[N];//原数组 
int tot;

//Pushup:子节点的值的上传给父亲节点 
void pushup(int root){
    t[root].val=t[t[root].lc].val+t[t[root].rc].val;
}


//单点修改  将范围[lt,rt]中的x节点加上v 
inline void update(int& root,int lt,int rt,int x,int v){
	if(!root) root=++tot;//如果没有建该节点就建出来 
    if(lt==rt){//找到了,任务完成=) 
    	t[root].val+=v; 
    	return; 
	}  
    //继续向下找
    int mid=lt+(rt-lt>>1);
    if(lt<=mid)update(t[root].lc,lt,mid,x,v);//如果修改的区间覆盖了左儿子就修改左子树
    if(rt>mid)update(t[root].rc,mid+1,rt,x,v);//右儿子同理
    pushup(root);//值上传 
} 

//区间查询  查询[lt,rt]范围中区间[l,r]的和 
ll query(int root,int lt,int rt,int l,int r){
	//点不存在直接返回0
	if(!root)return 0;
    //如果被覆盖,直接返回维护的值
    if(l<=lt&&r>=rt)  return t[root].val;
    int mid=lt+(rt-lt>>1);
    //累加查询的答案 
    ll ans=0;
    if(l<=mid)ans+=query(t[root].lc,lt,mid,l,r);
    if(r>mid)ans+=query(t[root].rc,mid+1,rt,l,r);
    return ans;
} 

int n,m,rt=1;
int main(){
    int n,m;
    scanf("%d%d",&n,&m); 
    for(int i=1;i<=n;i++){
        int num;
        scanf("%d",&num);
        update(rt,1,n,i,num);
    }
    while(m--){
        int op;
		scanf("%d",&op);
		if(op==1){
			int x,y,k;
			scanf("%d%d",&x,&k);
			update(rt,1,n,x,k);
		}else{
			int x,y;
			scanf("%d%d",&x,&y);
			printf("%lld\n",query(1,1,n,x,y));
		}
    }
    return 0;
} 
2023/8/16 10:35
加载中...