zoukankan      html  css  js  c++  java
  • [线段树]Skyscraper

    题目描述

    At the main street of Byteland, there will be built n skyscrapers, standing sequentially one next to other. If look leftside right, sequence of their height will be a1,a2,…,an.

    Initially the street is empty, every skyscraper's height is 0. Hamster is the leader of the construction team. In each stage, Hamster can select a range [l,r], then the team will work on this range. Specifically, assume the height sequence is h1,h2,…,hn, then hl,hl+1,…,hr will increase by 1 during this stage. When hi=ai holds for all i∈[1,n], the project will be closed.

    The plan may be changed for many times. There will be m events of 2 kinds below:

    ·1 l r k (1≤l≤r≤n,1≤k≤105), for all x∈[l,r], change ax to ax+k.
    ·2 l r (1≤l≤r≤n), assume a1,a2,…,al−1,ar+1,ar+2,…,an=0, ask for the minimum number of required stages to close the project.

    输入

    The first line of the input contains an integer T(1≤T≤1000), denoting the number of test cases.

    In each test case, there are two integers n,m(1≤n,m≤100000) in the first line, denoting the number of skyscrapers and events.

    In the second line, there are n integers a1,a2,...,an(1≤ai≤100000).

    For the next m lines, each line describes an event.

    It is guaranteed that ∑n≤106 and ∑m≤106.

    输出

    For each query event, print a single line containing an integer, denoting the answer.

    样例输入 Copy

    1
    5 4
    1 3 1 4 5
    2 1 5
    1 3 4 2
    2 2 4
    2 1 5
    

    样例输出 Copy

    7
    6
    6
    题意:对于序列a[1~n],有m个操作。1 l r k表示对[l,r]区间的数都加上k;2 l r表示询问使[l,r]区间完工的最小阶段数(一个阶段可以选择对一个子区间同时加1,当i点的值等于a[i]时,这点即完工)
    思路:使[l,r]区间完工的最小阶段数,就是∑max{a[i]-a[i-1],0}。即当a[i]>a[i-1]时,对答案贡献a[i]-a[i-1],否则对答案贡献0。
    所以我们要维护a[1~n]的差分序列d[1~n];对每一个询问[l,r],求a[l]+sum{max(d[l+1~r],0)}(a[l]=sum{d[1~l]})。线段树维护即可。
    AC代码:
    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    
    ll n,m;
    ll a[100005],d[100005];
    
    ll val[100005*4],sum[100005*4];
    
    void update(ll k){
      val[k]=val[k<<1]+val[k<<1|1];
      sum[k]=sum[k<<1]+sum[k<<1|1];
    }
    void build(ll k,ll l,ll r){
      if(l==r){
        val[k]=d[l];
        sum[k]=val[k]>0?val[k]:0;
        return;
      }
      ll mid=(l+r)>>1;
      build(k<<1,l,mid);
      build(k<<1|1,mid+1,r);
      update(k);
    }
    void modify(ll k,ll l,ll r,ll pos,ll v){
      if(l==r){
        val[k]+=v;
        sum[k]=val[k]>0?val[k]:0;
        return;
      }
      ll mid=(l+r)>>1;
      if(pos<=mid) modify(k<<1,l,mid,pos,v);
      else modify(k<<1|1,mid+1,r,pos,v);
      update(k);
    }
    ll query1(ll k,ll l,ll r,ll L,ll R){
      if(L>R) return 0;
      if(L<=l&&r<=R){
        return val[k];
      }
      ll ret=0;
      ll mid=(l+r)>>1;
      if(L<=mid) ret+=query1(k<<1,l,mid,L,R);
      if(R>mid) ret+=query1(k<<1|1,mid+1,r,L,R);
      return ret;
    }
    ll query2(ll k,ll l,ll r,ll L,ll R){
      if(L>R) return 0;
      if(L<=l&&r<=R){
        return sum[k];
      }
      ll ret=0;
      ll mid=(l+r)>>1;
      if(L<=mid) ret+=query2(k<<1,l,mid,L,R);
      if(R>mid) ret+=query2(k<<1|1,mid+1,r,L,R);
      return ret;
    }
    
    int main()
    {
        ll _;scanf("%lld",&_);
        while(_--){
            scanf("%lld%lld",&n,&m);
            for(ll i=1;i<=n;i++){
                scanf("%lld",&a[i]);
                d[i]=a[i]-a[i-1];
            }
            build(1,1,n);
            while(m--){
                ll op;scanf("%lld",&op);
                if(op==1){
                    ll l,r,k;scanf("%lld%lld%lld",&l,&r,&k);
                    modify(1,1,n,l,k);
                    if(r+1<=n) modify(1,1,n,r+1,-k);
                }
                else{
    
                    ll l,r;scanf("%lld%lld",&l,&r);
                    ll ans=query1(1,1,n,1,l)+query2(1,1,n,l+1,r);
                    printf("%lld
    ",ans);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    WinPE U盘安装原版Win10系统详细教程
    Foxmail for windows 客户端设置和 IMAP、POP3/SMTP 的设置
    微信打开X5调试,使微信页面可以在谷歌浏览器调试
    古今时辰对照表--选择吉日吉时,养生时辰必看
    2020爱你爱你,新的一年,新的开始,2020我想对你说
    人民日报推荐好文《善待你所在的单位》
    致大学生,我把私藏多年的的实用工具/学习网站都贡献出来了~~
    使用poco 的NetSSL_OpenSSL 搭建https 服务端,使用C++客户端,java 客户端访问,python访问(python还没找到带证书访问的代码.)
    C++ activemq CMS 学习笔记.
    关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记.
  • 原文地址:https://www.cnblogs.com/lllxq/p/11749527.html
Copyright © 2011-2022 走看看