Rt。用单调栈+线段树的写法,和题解里思路一样,但是在 #6 WA了,求大佬帮忙调调/kel
#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
int n,h[300005],b[300005],dp[300005];
stack<int>s;
class Segment_Tree
{
int w[1200005],d[1200005];
int l[1200005],r[1200005];
int lzy[1200005],f[1200005];
public:
void build(int ll,int rr,int k)
{
l[k]=ll,r[k]=rr;
w[k]=d[k]=-1e18;
if(ll==rr) return ;
int mid=(ll+rr)/2;
build(ll,mid,k*2);
build(mid+1,rr,k*2+1);
return ;
}
void down(int k)
{
lzy[k*2]=lzy[k*2+1]=lzy[k];
w[k*2]=d[k*2]+lzy[k];
w[k*2+1]=d[k*2+1]+lzy[k];
f[k*2]=f[k*2+1]=1;
f[k]=0;
return ;
}
void cover(int ll,int rr,int beauty,int k)
{
if(ll<=l[k]&&r[k]<=rr)
{
w[k]=d[k]+beauty;
lzy[k]=beauty;
f[k]=1;
return ;
}
if(f[k]) down(k);
int mid=(l[k]+r[k])/2;
if(ll<=mid) cover(ll,rr,beauty,k*2);
if(rr>mid) cover(ll,rr,beauty,k*2+1);
w[k]=max(w[k*2],w[k*2+1]);
}
void insert(int x,int y,int k)
{
if(l[k]==r[k]){d[k]=y;return ;}
if(f[k]) down(k);
int mid=(l[k]+r[k])/2;
if(x<=mid) insert(x,y,k*2);
else insert(x,y,k*2+1);
w[k]=max(w[k*2],w[k*2+1]);
d[k]=max(d[k*2],d[k*2+1]);
}
int query(){return w[1];}
}tr;
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
tr.build(0,n,1);
tr.insert(0,0,1);
for(int i=1;i<=n;i++)
{
while(!s.empty()&&h[s.top()]>h[i]) s.pop();
if(!s.empty()) tr.cover(s.top(),i-1,b[i],1);
else tr.cover(0,i-1,b[i],1);
s.push(i);
dp[i]=tr.query();
tr.insert(i,dp[i],1);
}
// for(int i=1;i<=n;i++) printf("%lld ",dp[i]);
printf("%d\n",dp[n]);
return 0;
}