求助线段树 WA on #6
查看原帖
求助线段树 WA on #6
195331
Mine_KingCattleya楼主2021/12/12 14:18

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;
}
2021/12/12 14:18
加载中...