差分,转化为两个单点修改和一个区间修改
维护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 "); else printf("%d ",query(1,1,n-1,s,t-1).F11); } } return 0; }