维护区间最小值,也就是盾的剩余护甲,如果有<=0的了就暴力下放到这个点。然后每次下放看叶子是不是盾已经破了,决定是*2还是不乘。因为每个盾最多破一次,所以总复杂度是ok的。
O(nlogn)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
#define mod 1000000009
inline char gc(){
static char buf[1<<16],*S,*T;
if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
char op[5];
inline void get_S(){
char ch=gc();
while(ch!='A'&&ch!='Q') ch=gc();op[1]=ch;return;
}
int n,a[N],m,ans=0;
struct node{
int add,mn;
}tr[N<<2];
inline void pushup(int p){
tr[p].mn=min(tr[p<<1].mn,tr[p<<1|1].mn);
}
inline void build(int p,int l,int r){
if(l==r){tr[p].mn=a[l]?a[l]:inf;return;}int mid=l+r>>1;
build(p<<1,l,mid);build(p<<1|1,mid+1,r);pushup(p);
}
inline void doadd(int p,int l,int r,int val);
inline void pushdown(int p,int l,int r){
if(!tr[p].add) return;int mid=l+r>>1;
doadd(p<<1,l,mid,tr[p].add);doadd(p<<1|1,mid+1,r,tr[p].add);
tr[p].add=0;pushup(p);
}
inline void doadd(int p,int l,int r,int val){
if(l==r){
tr[p].add+=val*(tr[p].mn==inf?2:1);
if(tr[p].mn==inf) return;tr[p].mn-=val;
if(tr[p].mn<=0) tr[p].mn=inf;return;
}tr[p].add+=val;tr[p].mn-=val;if(tr[p].mn<=0) pushdown(p,l,r);
}
inline void change(int p,int l,int r,int x,int y,int val){
if(x<=l&&r<=y){doadd(p,l,r,val);return;}
int mid=l+r>>1;pushdown(p,l,r);
if(x<=mid) change(p<<1,l,mid,x,y,val);
if(y>mid) change(p<<1|1,mid+1,r,x,y,val);pushup(p);
}
inline int ask(int p,int l,int r,int x){
if(l==r) return tr[p].add;
int mid=l+r>>1;pushdown(p,l,r);
if(x<=mid) return ask(p<<1,l,mid,x);
return ask(p<<1|1,mid+1,r,x);
}
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();
for(int i=1;i<=n;++i) a[i]=read();
build(1,1,n);
while(m--){
get_S();
if(op[1]=='A'){
int l=read(),r=read(),val=read();
change(1,1,n,l,r,val);
}else{
int x=read();(ans+=ask(1,1,n,x))%=mod;
}
}printf("%d\n",ans);
return 0;
}