H - Skyscraper Gym - 102220H (树状数组)

题目链接:

https://cn.vjudge.net/problem/Gym-102220H

题目大意:

懒得写了。。。,自己翻译吧

具体思路:

将整个数组转换成差分数组之后,就会发现所求的答案 [ l , r ] 就是a[l] + (b[l+1] ~ b[r])这段区间中非负的值的总和。

AC代码:

  1 #include
  2 #include
  3 #include
  4 using namespace std;
  5 # define ll long long
  6 # define inf 0x3f3f3f3f
  7 # define LL_inf (1ll<<60)
  8 const int mod = 1e9+7;
  9 const int maxn = 2e5+100;
 10 const int maxstate= 1e6+100;
 11 int a[maxn],b[maxn];
 12 ll tree_1[maxn],tree_2[maxn];
 13 int n,m;
 14 int lowbit(int pos)
 15 {
 16     return pos&-pos;
 17 }
 18 void add1(int val,int pos)/// 区间修改,单点查询
 19 {
 20     while(pos<maxn)
 21     {
 22         tree_1[pos]+=val;
 23         pos+=lowbit(pos);
 24     }
 25 }
 26 void add2(int val,int pos) /// 单点修改,区间查询
 27 {
 28     while(pos<maxn)
 29     {
 30         tree_2[pos]+=val;
 31         pos+=lowbit(pos);
 32     }
 33 }
 34 ll ask1(int pos)
 35 {
 36     if(pos==0)
 37         return 0;
 38     ll sum=0;
 39     while(pos)
 40     {
 41         sum+=tree_1[pos];
 42         pos-=lowbit(pos);
 43     }
 44     return sum;
 45 }
 46 ll  ask2(int pos)
 47 {
 48     if(pos==0)
 49         return 0;
 50     ll sum=0;
 51     while(pos)
 52     {
 53         sum+=tree_2[pos];
 54         pos-=lowbit(pos);
 55     }
 56     return sum;
 57 }
 58 int main()
 59 {
 60     int T;
 61     scanf("%d",&T);
 62     while(T--)
 63     {
 64         scanf("%d %d",&n,&m);
 65         for(int i=0; i<=n; i++)
 66         {
 67             tree_1[i]=0;
 68             tree_2[i]=0;
 69         }
 70         for(int i=1; i<=n; i++)
 71         {
 72             scanf("%d",&a[i]);
 73             b[i]=a[i]-a[i-1];
 74             int tmp=b[i] >0 ? b[i] : 0;
 75             add1(b[i],i);
 76             add2(tmp,i);
 77         }
 78         while(m--)
 79         {
 80             int type;
 81             scanf("%d",&type);
 82             if(type==1)
 83             {
 84                 int l,r,val;
 85                 scanf("%d %d %d",&l,&r,&val);
 86                 add1(val,l);
 87                 add1(-val,r+1);
 88                 if(b[l]<0)
 89                 {
 90                     int tmp=-b[l];
 91                     if(tmp<val)
 92                         add2(val-tmp,l);
 93                 }
 94                 else if(b[l]>=0)
 95                 {
 96                     add2(val,l);
 97                 }
 98                 b[l]+=val;
 99 
100                 if(b[r+1]>=0)
101                 {
102                     int tmp=min(b[r+1],val);
103                     add2(-tmp,r+1);
104                 }
105                 b[r+1]-=val;
106             }
107             else if(type==2)
108             {
109                 int l,r;
110                 scanf("%d %d",&l,&r);
111                 printf("%lld\n",ask2(r)-ask2(l)+ask1(l));
112             }
113         }
114     }
115     return 0;
116 }

 

转载于:https://www.cnblogs.com/letlifestop/p/11043869.html

你可能感兴趣的:(H - Skyscraper Gym - 102220H (树状数组))