hdu-6315

http://acm.hdu.edu.cn/showproblem.php?pid=6315

题意:

给定数组a和b,b的值已知,a的值一开始都是0

两个操作,操作一是 add l r 给a数组l到r的值都加1,操作二是query l r 查询区间ai/bi的和.

题解:线段树维护ai和bi的大小关系就行,当每次操作了一次区间的ai值,这个时候bi就减1,当bi减到0的时候sum值就加1.

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
#define llinf 1e18
#define inf 1e9
const int N=1e6+6;
int n,m;
int minn[N*4],b[N],sum[N*4],lazy[N*4];
void pushdown(int rt){
    if(lazy[rt]){
        lazy[ls]+=lazy[rt];
        lazy[rs]+=lazy[rt];
        minn[ls]-=lazy[rt];
        minn[rs]-=lazy[rt];
        lazy[rt]=0;
    }
}
void pushup(int rt){
    sum[rt]=sum[ls]+sum[rs];
    minn[rt]=min(minn[ls],minn[rs]);
}
void build(int l,int r,int rt){
    lazy[rt]=0;
    sum[rt]=0;
    if(l==r){
        minn[rt]=b[l];
        return ;
    }
    int m=(l+r)/2;
    build(l,m,ls);
    build(m+1,r,rs);
    pushup(rt);
}
void update(int L,int R,int l,int r,int rt){
    if(L<=l&&R>=r&&minn[rt]>1){
        lazy[rt]++;
        minn[rt]--;
        return ;
    }
    if(l==r&&minn[rt]==1){
        sum[rt]++;
        lazy[rt]=0;
        minn[rt]=b[l];
        return ;
    }
    int m=(l+r)/2;
    pushdown(rt);
    if(L<=m) update(L,R,l,m,ls);
    if(R>m) update(L,R,m+1,r,rs);
    pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
    if(L<=l&&R>=r){
        return sum[rt];
    }
    if(minn[rt]==0) update(L,R,1,n,1);
    int m=(l+r)/2;
    int ans=0;
    pushdown(rt);
    if(L<=m) ans+=query(L,R,l,m,ls);
    if(R>m) ans+=query(L,R,m+1,r,rs);
    pushup(rt);
    return ans;
}
int main(int argc, char * argv[]) {
       while(~scanf("%d%d",&n,&m)){
           for(int i=1;i<=n;i++){
               scanf("%d",&b[i]);
           }
           build(1,n,1);
           while(m--){
               char s[10];
               scanf("%s",s);
               int l,r;
               scanf("%d%d",&l,&r);
               if(s[0]=='a') update(l,r,1,n,1);
               else printf("%d\n",query(l,r,1,n,1));
           }
       }
    return 0;
}

 

posted @ 2019-10-30 20:12  wushuyng  阅读(212)  评论(0编辑  收藏  举报