• H. Skyscraper题解(线段树+差分数组)


    题目链接

    题目大意

    两个操作

    1:使得区间整体加k

    2:求a[l]+max(0,a[l+1]-a[l])+max(0,a[l+2]-a[l+1])+...max(0,a[r]-a[r-1])

    题目思路

    用两颗线段树维护差分数组即可

    第一颗线段树就是维护普通的差分数组

    第二颗就是把负数变为0的线段树

    然后a[l]可以根据第一颗线段树的前缀和求的

    max(0,a[l+1]-a[l])+max(0,a[l+2]-a[l+1])+...max(0,a[r]-a[r-1]) 则直接是第二颗线段树的区间和

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define fi first
    #define se second
    #define debug printf("aaaaaaaaaaa\n");
    const int maxn=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    int n,m;
    int a[maxn];
    ll tree[maxn<<2][2];
    void update(int node,int pos,int val,int l,int r){
        if(l==r){
            tree[node][0]+=val;
            tree[node][1]=max(1ll*0,tree[node][0]);
            return ;
        }
        int mid=(l+r)/2;
        if(mid>=pos) update(node<<1,pos,val,l,mid);
        else update(node<<1|1,pos,val,mid+1,r);
        tree[node][0]=tree[node<<1][0]+tree[node<<1|1][0];
        tree[node][1]=tree[node<<1][1]+tree[node<<1|1][1];
    }
    ll query(int node,int L,int R,int l,int r,int id){
        if(L<=l&&r<=R){
            return tree[node][id];
        }
        int mid=(l+r)/2;
        ll sum=0;
        if(mid>=L) sum+=query(node<<1,L,R,l,mid,id);
        if(mid<R) sum+=query(node<<1|1,L,R,mid+1,r,id);
        return sum;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        int _; cin>>_;
        while(_--){
            cin>>n>>m;
            for(int i=1;i<=4*n;i++){
                tree[i][0]=tree[i][1]=0;            
            }
            for(int i=1;i<=n;i++){
                cin>>a[i];
                update(1,i,a[i]-a[i-1],1,n);
            }
            for(int i=1,opt,l,r,k;i<=m;i++){
                cin>>opt>>l>>r;
                if(opt==1){
                    cin>>k;
                    update(1,l,k,1,n);
                    if(r!=n){
                        update(1,r+1,-k,1,n);
                    }
                }else{
                    ll ans=query(1,1,l,1,n,0);
                    if(l!=r){
                        ans+=query(1,l+1,r,1,n,1);
                    }
                    cout<<ans<<'\n';
                }
            }
        }
        return 0;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    正则基础之——反向引用
    zend framework 配置连接数据库
    Zend Framework Module之多模块配置
    zend framework 1.10项目配置与经典hello world
    CSS3 @font-face
    js跳转页面方法(转)
    CSS中怎么让DIV居中
    HTML段落自动换行的样式设置
    PHPEXCEL实例-导出EXCEL
    移动端框架篇-控制父容器的滑屏框架-slip.js
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15017655.html
Copyright © 2020-2023  润新知