这题看题面就知道是线段树了,但是我们发现 这个式子并不是很好维护,那么我们可以换一个思路,对于每个add操作,我们把B序列的对应区间-1,当B序列中某个位置上为0的时候,这个位置的答案就+1 并且把这个值又变回到Bi 这个很好理解 所以我们要维护区间的最小值来看-1后以后会不会有位置变成0 对于会变成0的位置我们需要单点更新 有些人可能觉得 如果有多个位置同时为1的话 复杂度会很高 其实不然 首先多个位置同时为1 需要很多次add操作 这一定程度上降低了query操作的次数 其次保证了效率的是 Bi是一个全排列 显然当为1的多个位置被更新后 又会变成完全不相同的数 可以保证复杂度(不会证明具体的复杂度)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
struct seg_tree{
int l,r;
ll sum,add,mi;
}T[N<<2];
ll b[N];
int n,q;
void pushup(int id){
T[id].mi=min(T[id<<1].mi,T[id<<1|1].mi);
T[id].sum=T[id<<1].sum+T[id<<1|1].sum;
}
void pushdown(int id){
if(T[id].add){
T[id<<1].mi+=T[id].add;
T[id<<1|1].mi+=T[id].add;
T[id<<1].add+=T[id].add;
T[id<<1|1].add+=T[id].add;
T[id].add=0;
}
}
void build(int id,int l,int r){
T[id].l=l,T[id].r=r,T[id].add=T[id].sum=0;
if(l==r){
T[id].mi=1ll*b[l];
return;
}
int mid = l+r>>1;
build(id<<1,l,mid);build(id<<1|1,mid+1,r);
pushup(id);
}
void update(int id,int L,int R,ll val){
// printf("T[id].l=%d T[id].r=%d\n",T[id].l,T[id].r);
if(L<=T[id].l&&R>=T[id].r&&T[id].mi>1){
T[id].add+=val;
T[id].mi+=val;
return;
}
if(T[id].l==T[id].r&&T[id].mi==1){
T[id].add=0;
T[id].sum++;
T[id].mi=b[T[id].l];
return;
}
pushdown(id);
int mid = T[id].l+T[id].r>>1;
if(L<=mid) update(id<<1,L,R,val);
if(R>mid) update(id<<1|1,L,R,val);
pushup(id);
}
ll query(int id,int L,int R){
if(L<=T[id].l&&R>=T[id].r){
return T[id].sum;
}
ll ans = 0;
int mid = T[id].l+T[id].r>>1;
pushdown(id);
if(L<=mid) ans+=query(id<<1,L,R);
if(R>mid) ans+=query(id<<1|1,L,R);
return ans;
}
void debug(int id){
//printf("T[id].l=%d T[id].r=%d T[%d].add=%lld\n",T[id].l,T[id].r,id,T[id].add);
if(T[id].l==T[id].r){
return;
}
pushdown(id);
int mid = T[id].l+T[id].r>>1;
debug(id<<1);debug(id<<1|1);
}
int main(){
while(~scanf("%d%d",&n,&q)){
for(int i = 1; i <= n; i++) scanf("%lld",&b[i]);
char s[10];
int l,r;
build(1,1,n);
for(int i = 1; i <= q; i++){
scanf("%s%d%d",s,&l,&r);
if(s[0]=='a'){
update(1,l,r,-1ll);
}else{
printf("%lld\n",query(1,l,r));
}
//debug(1);
}
}
return 0;
}
/*
9 8
9 4 7 2 5 6 1 3 8
a 1 9
a 1 2
q 1 3
q 4 7
a 1 4
a 1 1
q 3 7
q 1 4
*/