Naive Operations

线段树简单维护

一开始没看见b是排列

。。。

#include<cstdio>
#include<iostream>
#include<algorithm>
const int maxn = 100100;
int n,q;
int b[maxn];
int max[maxn<<2],sum[maxn<<2],tag[maxn<<2];
inline void puttag(int cur,int s){ max[cur]+=s,tag[cur]+=s; }
inline void pushdown(int cur){puttag(cur<<1,tag[cur]),puttag(cur<<1|1,tag[cur]),tag[cur]=0;}
inline void update(int cur){
    max[cur]=std::max(max[cur<<1],max[cur<<1|1]);
    sum[cur]=sum[cur<<1]+sum[cur<<1|1];
}
inline void modify(int cur,int L,int R,int l=1,int r=n){
    if(l == r){
        if(++max[cur]==0)max[cur]=-b[l],++sum[cur];
        return ;
    }
    if(L <= l && r <= R && max[cur] != -1)return puttag(cur,1);
    pushdown(cur);
    int mid=l+r>>1;
    if(L<=mid)modify(cur<<1,L,R,l,mid);
    if(mid<R)modify(cur<<1|1,L,R,mid+1,r);
    update(cur);
}
inline int query(int cur,int L,int R,int l=1,int r=n){
    if(L <= l && r <= R)return sum[cur];
    int mid=l+r>>1,ans=0;
    pushdown(cur);
    if(L<=mid)ans+=query(cur<<1,L,R,l,mid);
    if(mid<R)ans+=query(cur<<1|1,L,R,mid+1,r);
    return ans;
}
inline void build(int cur,int l,int r){
    tag[cur]=max[cur]=sum[cur]=0;
    if(l==r)return void(max[cur]=-b[l]);
    int mid=l+r>>1;
    build(cur<<1,l,mid),build(cur<<1|1,mid+1,r);
    update(cur);
}
int main(){
    std::ios::sync_with_stdio(false),std::cin.tie(0);
    while(std::cin >> n >> q){
        for(int i=1;i<=n;++i)std::cin >> b[i];
        build(1,1,n);
        char opt[10]={};
        for(int i=1,l,r;i<=q;++i){
            std::cin >> opt >> l >> r;
            if(*opt=='a')modify(1,l,r);
            else std::cout << query(1,l,r) << '
';
        }
    }
}
原文地址:https://www.cnblogs.com/skip1978/p/10333538.html