差分,转化为两个单点修改和一个区间修改
维护00,01,10,11表示左右端点取或不取的最小值
线段树即可
#include<cstdio>
#include<algorithm>
using namespace std;
int n,tag[550005],a[100005];
char s[15];
struct node{
int F00,F01,F10,F11,l,r;
}tree[550005];
node merge(node L,node R){
node ans;
ans.l=L.l,ans.r=R.r;
int val=(L.r==R.l);
ans.F00=L.F01+R.F10-val;
ans.F00=min(ans.F00,L.F00+R.F10);
ans.F00=min(ans.F00,L.F01+R.F00);
ans.F01=L.F01+R.F11-val;
ans.F01=min(ans.F01,L.F00+R.F11);
ans.F01=min(ans.F01,L.F01+R.F01);
ans.F10=L.F11+R.F10-val;
ans.F10=min(ans.F10,L.F10+R.F10);
ans.F10=min(ans.F10,L.F11+R.F00);
ans.F11=L.F11+R.F11-val;
ans.F11=min(ans.F11,L.F10+R.F11);
ans.F11=min(ans.F11,L.F11+R.F01);
return ans;
}
void push_down(int t){
tag[t<<1]+=tag[t],tag[t<<1|1]+=tag[t];
tree[t<<1].l+=tag[t],tree[t<<1].r+=tag[t];
tree[t<<1|1].l+=tag[t],tree[t<<1|1].r+=tag[t];
tag[t]=0;
}
void build(int t,int l,int r){
if (l==r){
int val=a[l+1]-a[l];
tree[t]=(node){0,1,1,1,val,val};
return;
}
int mid=(l+r)>>1;
build(t<<1,l,mid);
build(t<<1|1,mid+1,r);
tree[t]=merge(tree[t<<1],tree[t<<1|1]);
}
void modify(int t,int l,int r,int x,int y,int w){
if (l>y || r<x) return;
if (l>=x && r<=y){
tree[t].l+=w,tree[t].r+=w;
tag[t]+=w;
return;
}
if (tag[t]) push_down(t);
int mid=(l+r)>>1;
modify(t<<1,l,mid,x,y,w);
modify(t<<1|1,mid+1,r,x,y,w);
tree[t]=merge(tree[t<<1],tree[t<<1|1]);
}
node query(int t,int l,int r,int x,int y){
if (l==x && r==y) return tree[t];
if (tag[t]) push_down(t);
int mid=(l+r)>>1;
if (y<=mid) return query(t<<1,l,mid,x,y);
if (x>mid) return query(t<<1|1,mid+1,r,x,y);
return merge(query(t<<1,l,mid,x,mid),query(t<<1|1,mid+1,r,mid+1,y));
}
int main(){
scanf("%d",&n);
for (int i=1; i<=n; i++) scanf("%d",&a[i]);
build(1,1,n-1);
int q;
scanf("%d",&q);
while (q--){
scanf("%s",s);
if (s[0]=='A'){
int s,t,a,b;
scanf("%d%d%d%d",&s,&t,&a,&b);
if (s-1) modify(1,1,n-1,s-1,s-1,a);
if (s!=t) modify(1,1,n-1,s,t-1,b);
if (t<n) modify(1,1,n-1,t,t,-(t-s)*b-a);
}
else if (s[0]=='B'){
int s,t;
scanf("%d%d",&s,&t);
if (s==t) printf("1\n");
else printf("%d\n",query(1,1,n-1,s,t-1).F11);
}
}
return 0;
}