1 条题解

  • 1
    @ 2025-5-11 1:52:29

    线段树的区间修改和单点查询

    这题要关同步流,不然cin过不了

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+9;
    #define int long long
    int n,a[N],m,x,l,r,op;
    struct t{
        int l,r,data,add;//注意懒标记的使用
    }tree[4*N];
    
    void pushup(int k){//向上更新
      
    tree[k].data=tree[2*k].data+tree[2*k+1].data;
    }
    void update(int k){//向下更新,传递懒标记
        if(!tree[k].add) return;
        tree[2*k].data+=(tree[2*k].r-tree[2*k].l+1)*tree[k].add;
        tree[2*k+1].data+=(tree[2*k+1].r-tree[2*k+1].l+1)*tree[k].add;
        tree[2*k].add+=tree[k].add;
        tree[2*k+1].add+=tree[k].add;
        tree[k].add=0;
    }
    void change(int k,int l,int r,int x){
        if(l<=tree[k].l&&tree[k].r<=r){
            tree[k].data+=(tree[k].r-tree[k].l+1)*x;
            tree[k].add+=x;
            return;
        }
        update(k);
        int mid=(tree[k].l+tree[k].r)>>1;
        if(l<=mid) change(2*k,l,r,x);
        if(r>mid) change(2*k+1,l,r,x);
        pushup(k);
    }
    int query(int k,int idx){
        if(tree[k].l==tree[k].r) return tree[k].data;
        update(k);
        int mid=(tree[k].l+tree[k].r)>>1;
        return (idx<=mid) ? query(2*k,idx) : query(2*k+1,idx);
    }
    void build(int k,int l,int r){
        tree[k]={l,r,a[l],0};
        if(l==r) return;
        int mid=(l+r)>>1;
        build(2*k,l,mid);
        build(2*k+1,mid+1,r);
        pushup(k);
    }
    signed main(){
        ios::sync_with_stdio(false); cin.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i];
        build(1,1,n);
        while(m--){
            cin>>op;
            if(op==1){
                cin>>l>>r>>x;
                change(1,l,r,x);
            }else{
                cin>>x;
                cout<<query(1,x)<<'\n';
            }
        }
        return 0;
    }
    

    信息

    ID
    58
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    84
    已通过
    23
    上传者