1. 程式人生 > 其它 >題解 CF722C 【Destroying Array】

題解 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