zoukankan      html  css  js  c++  java
  • HDU 6315 Naive Operations <<线段树

    题意

    在一个数据结构上实现区间加一,询问区间内$a_i/b_i$的和,$b_i$是事先给出的一个序列

    思路

    线段树维护区间最小值与区间和,区间最小值维护$a_i$序列,每次加操作区间最小值减一,如果最小值减到零,就去暴力更新区间和,区间和维护的是答案的和。

    代码

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1e5+7;
      4 struct node{
      5     int b,low,sum;
      6 }sgt[maxn*4];
      7 int lazy[maxn*4];
      8 void pushup(int rt)
      9 {
     10     sgt[rt].low=min(sgt[rt*2].low,sgt[rt*2+1].low);
     11     sgt[rt].sum=sgt[rt*2].sum+sgt[rt*2+1].sum;
     12 }
     13 void pushdown(int L,int R,int rt)
     14 {
     15     if(lazy[rt])
     16     {
     17         sgt[rt*2].low-=lazy[rt];
     18         sgt[rt*2+1].low-=lazy[rt];
     19         lazy[rt*2]+=lazy[rt];
     20         lazy[rt*2+1]+=lazy[rt];
     21         lazy[rt]=0;
     22     }
     23     if(sgt[rt].low<=0)
     24     {
     25         if(L==R)
     26         {
     27             while(sgt[rt].low<=0)
     28             {
     29                 sgt[rt].low+=sgt[rt].b;
     30                 sgt[rt].sum++;
     31             }
     32             return;
     33         }
     34         int mid=L+R>>1;
     35         pushdown(L,mid,rt*2);
     36         pushdown(mid+1,R,rt*2+1);
     37         pushup(rt);
     38     }
     39 }
     40 void build(int l,int r,int rt)
     41 {
     42     if(l==r)
     43     {
     44         scanf("%d",&sgt[rt].b);
     45         sgt[rt].low=sgt[rt].b;
     46         return;
     47     }
     48     int mid=l+r>>1;
     49     build(l,mid,rt*2);
     50     build(mid+1,r,rt*2+1);
     51     pushup(rt);
     52 }
     53 void update(int l,int r,int L,int R,int rt)
     54 {
     55     pushdown(L,R,rt);
     56     if(L>=l&&R<=r)
     57     {
     58         sgt[rt].low-=1;
     59         lazy[rt]+=1;
     60         return ;
     61     }
     62     int mid=L+R>>1;
     63     if(mid>=l)
     64         update(l,r,L,mid,rt*2);
     65     if(mid<r)
     66         update(l,r,mid+1,R,rt*2+1);
     67     pushup(rt);
     68 }
     69 int query(int l,int r,int L,int R,int rt)
     70 {
     71     pushdown(L,R,rt);
     72     if(L>=l&&R<=r)
     73     {
     74         return sgt[rt].sum;
     75     }
     76     int mid=L+R>>1;
     77     int ret=0;
     78     if(mid>=l)
     79         ret+=query(l,r,L,mid,rt*2);
     80     if(mid<r)
     81         ret+=query(l,r,mid+1,R,rt*2+1);
     82     return ret;
     83 }
     84 int main()
     85 {
     86     int n,q;
     87     while(~scanf("%d%d",&n,&q))
     88     {
     89         memset(sgt,0,sizeof(sgt));
     90         memset(lazy,0,sizeof(lazy));
     91         build(1,n,1);
     92         char op[10];
     93         while(q--)
     94         {
     95             int l,r;
     96             scanf("%s",op);
     97             scanf("%d%d",&l,&r);
     98             if(op[0]=='a')
     99                 update(l,r,1,n,1);
    100             else{
    101                 int ans=query(l,r,1,n,1);
    102                 printf("%d
    ",ans);
    103             }
    104         }
    105     }
    106 }

    后记

    还是要学会线段树的灵活运用的!感觉提升了一点对线段树的认识。

  • 相关阅读:
    Java内存模型
    Redis的复制特性
    Redis数据持久化
    Java的三种代理模式
    设计模式—模板方法模式
    设计模式—观察者模式
    web性能优化之:no-cache与must-revalidate深入探究
    JWT
    数值每三位加逗号
    Webpack 打包优化之速度篇
  • 原文地址:https://www.cnblogs.com/computer-luo/p/10095808.html
Copyright © 2011-2022 走看看