zoukankan      html  css  js  c++  java
  • ll 1164 线段树

    1164 - 战舰萝莉

    Time Limit:2s Memory Limit:256MByte

    Submissions:85Solved:42

    DESCRIPTION

    在大战之后,法力浮·鳝AK迅速驾船驶向北海。当然他知道水之灵不可能那么容易得到,正如爱迪生曾说过:“要把BOSS打倒就要准备足够的等级。”所以鳝氪金招募了一队海盗以防战斗。
    果不其然,正当鳝看见了水之灵的所在时,一大队舰娘(雾),一大队舰船突然闪现,大战一触即发。
    大战前,鳝被对面的boss——北方栖姬吸引了,北方栖姬是一个可爱的小萝莉,实力却很是强劲,而鳝打算把她诱拐回家(雾),打算把她策略击破。
    鳝通过提督的观察,发现北方栖姬摆出了“线段树阵形”,具体是这样的:
    可以将深海栖舰的舰队看作对一个长度为n的序列建成的线段树,线段树的每个节点维护区间和,记作sumv[o]。这个值同时也是该节点的敌舰所具有的火力。同时在作战过程中,北方栖姬会不断发出区间加和区间减的指令,请注意,这些指令是以打标记的形式维护的,换而言之,某些点的sumv可能不会及时更新。
    在每次敌舰队发生变化之后,鳝会问你,当前敌舰队有多少舰是“有威胁”的,我们称一艘舰是有威胁的当且仅当这艘舰的火力>k(一个给定常数)。
    作为鳝船上的一名海盗,您需要回答法力浮鳝的所有询问。
    下面给出敌舰队的建成,修改的具体示例代码:
    http://paste.ubuntu.com/25598285/

    INPUT
    输入的第一行三个整数n,m,k,m表示操作次数。 接下来一行n个整数,表示线段树维护的原序列。 接下来m行,每行四个整数opt,l,r,x 如果opt=1表示区间加,反之则是区间减。表示在[l,r]加上或者减去x
    OUTPUT
    共m行,每行一个整数表示每次操作后的答案。
    SAMPLE INPUT
    8 2 20 1 2 3 4 5 6 7 8 2 1 8 100 1 1 3 20
    SAMPLE OUTPUT
    1 0
    HINT
    1 ≤ n ,m≤ 100000,序列值,k和sumv[o]始终在int范围内,可能出现负数
       A盯了一个小时后发现不会= =再看这道为什么这么水!难道第一题不是签到题- -!
    代码都给出来了,xjb改一下维护一个总值k就好了,在修改函数pushdown里面维护。
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int a[100005];
     4 int sumv[400005];
     5 int addv[400005];
     6 int ans=0,K;
     7 struct SegTree
     8 {
     9 #define lson (o<<1)
    10 #define rson (o<<1|1)
    11 inline void pushup(int o)
    12 {
    13     int tmp=sumv[lson]+sumv[rson];
    14     if(sumv[o]<=K&&tmp>K) ans++;
    15     if(sumv[o]>K&&tmp<=K) ans--;
    16     sumv[o]=tmp;
    17 }
    18 inline void pushdown(int o,int l,int r){
    19      if(!addv[o]) {return;}
    20      int mid=(l+r)>>1,tag=addv[o];
    21      addv[lson]+=tag;addv[rson]+=tag;
    22      int tmp1=sumv[lson]+tag*(mid-l+1);
    23      int tmp2=sumv[rson]+tag*(r-mid);
    24      if(sumv[lson]<=K&&tmp1>K) ans++;
    25      if(sumv[lson]>K&&tmp1<=K) ans--;
    26      if(sumv[rson]<=K&&tmp2>K) ans++;
    27      if(sumv[rson]>K&&tmp2<=K) ans--;
    28      sumv[lson]=tmp1;
    29      sumv[rson]=tmp2;
    30      addv[o]=0;
    31 }
    32 inline void build(int o,int l,int r){
    33      if(l==r){sumv[o]=a[l];if(sumv[o]>K)ans++;return;}
    34      int mid=(l+r)>>1;
    35      build(lson,l,mid);
    36      build(rson,mid+1,r);
    37      pushup(o);
    38 }
    39 inline void optadd(int o,int l,int r,int ql,int qr,int v){
    40      if(ql<=l&&r<=qr){int tmp=v*(r-l+1);
    41      if(sumv[o]<=K&&sumv[o]+tmp>K) ans++;
    42      if(sumv[o]>K&&sumv[o]+tmp<=K) ans--;
    43      sumv[o]+=tmp;
    44      addv[o]+=v;
    45      return;
    46    }
    47      int mid=(l+r)>>1;
    48      pushdown(o,l,r);
    49      if(ql<=mid)optadd(lson,l,mid,ql,qr,v);
    50      if(qr>mid)optadd(rson,mid+1,r,ql,qr,v);
    51      pushup(o);
    52 }
    53 }seg;
    54 int main()
    55 {
    56     int N,M;
    57     while(scanf("%d%d%d",&N,&M,&K)!=EOF){ans=0;
    58         for(int i=1;i<=N;++i) scanf("%d",a+i);
    59         memset(addv,0,sizeof(addv));
    60         seg.build(1,1,N);//cout<<ans<<endl;
    61         int opt,l,r,x;
    62         while(M--){
    63             scanf("%d%d%d%d",&opt,&l,&r,&x);
    64             if(opt==2) x=-x;
    65             seg.optadd(1,1,N,l,r,x);
    66             printf("%d
    ",ans);
    67         }
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/zzqc/p/7588621.html
Copyright © 2011-2022 走看看