题解 CF722C 【Destroying Array】

CF722C Destroying Array

题目大意:

给定由 \(n\) 个非负整数组成的数列 \(\lbrace a_i\rbrace\) 每次可以删除一个数,求每次删除操作后的最大连续子序列。

solution:

不难想到,我们可以使用一种支持修改和查询的数据结构。每次删除等价于把下标为 \(i\) 的数修改成一个极小值,此时的最大连续子序列就不会选择这个数。维护最大连续子序列的实现可以参考这道题

接下来是细节的处理:

  1. 题目中 \(0<=a<=10^9\) 且 \(1<=n<=10^5\) 最大连续子序列的和会超过 \(\text {int}\) 我们需要开个 \(\text{long long }\)。
  2. 删除的数要修改成一个极小值 \(-9\times 10^{13}\) ,但是这样写会有一个问题,相信聪明的你一定能解决 (其实也是对思路理解的反馈)。
  3. 对于查询,我们只输出根节点的信息就可以了。

看到这的同学,可以自己去写代码了(tf口吻)

代码
#include<cstdio>
#define ls u<<1
#define rs u<<1|1
using namespace std;
typedef long long LL;
const int N=1e5+5;
const LL INF=-90000000000000LL;
int a[N];
struct shu{
	int l,r;
	LL lmax,rmax,sum,smax;
}tr[N<<2];
inline LL maxx(LL x,LL y){return x>=y?x:y;}
inline void pushup(int u){
	tr[u].sum=tr[ls].sum+tr[rs].sum;
	tr[u].lmax=maxx(tr[ls].lmax,tr[ls].sum+tr[rs].lmax);
	tr[u].rmax=maxx(tr[rs].rmax,tr[rs].sum+tr[ls].rmax);
	tr[u].smax=maxx(maxx(tr[ls].smax,tr[rs].smax),tr[ls].rmax+tr[rs].lmax);
}
inline void build(int u,int l,int r){
	tr[u].l=l,tr[u].r=r;
	if(l==r){
		tr[u].lmax=a[l],tr[u].rmax=a[l],
		tr[u].sum=a[l], tr[u].smax=a[l];
		return ;
	}
	int mid=l+r>>1;
	build(ls,l,mid),build(rs,mid+1,r);
	pushup(u);
}
inline void gai(int u,int x,LL y){
	int l=tr[u].l,r=tr[u].r;
	if(l==x&&x==r){
		tr[u].lmax=y,tr[u].rmax=y,
		tr[u].smax=y, tr[u].sum=y;
		return ;
	}
	int mid=l+r>>1;
	if(x<=mid) gai(ls,x,y);
	else	   gai(rs,x,y);
	pushup(u);
}
int main()
{   
	int n;scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=1;i<=n;i++){
		int x;scanf("%d",&x);
		gai(1,x,INF);
		LL ans=tr[1].smax;
		printf("%lld\n",maxx(ans,0));
	}
	return 0;
}

End

上一篇:Codeforces Round #742 (Div. 2)


下一篇:P7405-[JOI 2021 Final]雪玉【二分】