https://nanti.jisuanke.com/t/48303
dp[i]=max Sigma(j=0 to i-1) max(sum黑[i]-sum黑[j]+dp[j]+ c黑[j+1,i] , sum白[i]-sum白[j]+dp[j]+ c白[j+1,i])
c[i,j]可以用线段树维护
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #define rep(i,a,b) for(int i=a;i<=b;i++) #define inf 9999999999 #define MAXN 300005 using namespace std; typedef long long ll; struct zlk{ int w,l,r; ll val; }; vector<pair<int,ll> > in1[MAXN],in2[MAXN]; int n,m; ll a[MAXN],b[MAXN],sa[MAXN],sb[MAXN],ans[MAXN]; struct Segment_Tree{ ll ma[MAXN<<2],tag[MAXN<<2]; void push_down(int k){ tag[k<<1]+=tag[k]; tag[(k<<1)|1]+=tag[k]; ma[k<<1]+=tag[k]; ma[(k<<1)|1]+=tag[k]; tag[k]=0; } void ins(int k,int l,int r,int x,int y,ll z){ // cout<<l<<" "<<r<<" "<<x<<" "<<y<<" "<<z<<endl; if(x<=l && r<=y){ tag[k]+=z; ma[k]+=z; return; } push_down(k); int mid=(l+r)>>1; if(mid>=x) ins(k<<1,l,mid,x,y,z); if(mid<y) ins((k<<1)|1,mid+1,r,x,y,z); ma[k]=max(ma[k<<1],ma[(k<<1)|1]); } ll query(int k,int l,int r,int x,int y){ if(x<=l && r<=y) return ma[k]; int mid=(l+r)>>1; ll maxx=-inf; if(x<=mid) maxx=query(k<<1,l,mid,x,y); if(mid<y) maxx=max(maxx,query((k<<1)|1,mid+1,r,x,y)); return maxx; } }P,Q; int main(){ scanf("%d%d",&n,&m);n++; rep(i,2,n) scanf("%lld",&a[i]),sa[i]=sa[i-1]+a[i]; rep(i,2,n) scanf("%lld",&b[i]),sb[i]=sb[i-1]+b[i]; rep(i,1,m){ int w,l,r; ll val; scanf("%d%d%d%lld",&w,&l,&r,&val); ++l; ++r; if(w==1) in1[r].push_back(make_pair(l,val)); else in2[r].push_back(make_pair(l,val)); } rep(i,2,n){ for(auto it:in1[i]) P.ins(1,1,n,1,it.first-1,it.second); for(auto it:in2[i]) Q.ins(1,1,n,1,it.first-1,it.second); // sum[i]=sum[i-1]+max(a[i],b[i]); ans[i]=max(sa[i]+P.query(1,1,n,1,i-1),sb[i]+Q.query(1,1,n,1,i-1)); P.ins(1,1,n,i,i,ans[i]-sa[i]); Q.ins(1,1,n,i,i,ans[i]-sb[i]); // printf("%lld %lld %lld ",ans[i],sa[i],sb[i]); } printf("%lld",ans[n]); return 0; }