一眼线段树
查看原帖
一眼线段树
573963
wbh20090611楼主2024/7/19 16:29

线段树单点修改+区间查询

//线段树模板 
#include<bits/stdc++.h>
using namespace std;
#define int long long //不开longlong见祖宗 
const int N=1000005;
//线段树变量定义 
int sum[N<<2];//求和 
int maxn[N<<2];//最大值 
int minn[N<<2];//最小值 
int tr[N<<2];//懒标记 
int a[N];//原数组 
int n;//总个数 
void pushdown(int,int,int);
void build(int root,int l,int r){//建树 
    if(l==r){//找到叶子节点 
        maxn[root]=minn[root]=sum[root]=a[l];
        return;
    }
    //不是叶子节点继续二分查询 
    int mid=(l+r)>>1;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
    //回溯各个值 
    maxn[root]=max(maxn[root<<1],maxn[root<<1|1]);
    minn[root]=min(minn[root<<1],maxn[root<<1|1]);
    sum[root]=sum[root<<1]+sum[root<<1|1];
    return;
}
int get_sum(int root,int l,int r,int qx,int qy){
    if(l>=qx&&r<=qy)return sum[root];
    int mid=(l+r)>>1,ans=0;
    if(qx<=mid)ans+=get_sum(root<<1,l,mid,qx,qy);
    if(qy>mid)ans+=get_sum(root<<1|1,mid+1,r,qx,qy);
    return ans+tr[root];
}
void update(int root,int l,int r,int pos,int val){
    if(l==r){
        sum[root] = val;
        return;
    }
    int mid=(l+r)/2;
    if(pos<=mid)update(root<<1,l,mid,pos,val);
    else update(root<<1|1,mid+1,r,pos,val);
    maxn[root]=max(maxn[root<<1],maxn[root<<1|1]);
    minn[root]=min(minn[root<<1],maxn[root<<1|1]);
    sum[root]=sum[root<<1]+sum[root<<1|1];
    return;
}
main(){
    int m;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",a+i);
    build(1,1,n);
    update(1, 1, n, m, -a[m]);
    cout << get_sum(1, 1, n, 1, n);
}
2024/7/19 16:29
加载中...