线段树优化DP求调
查看原帖
线段树优化DP求调
763878
Jerry_heng楼主2024/4/29 10:14

50 pts

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mxn=2e5+10;
int T,n,a[mxn],dp[mxn],tag[mxn<<2],mx[mxn<<2];
void pushdown(int o){
	if(tag[o]){
		tag[o*2]+=tag[o];
		tag[o*2+1]+=tag[o];
		mx[o*2]+=tag[o];
		mx[o*2+1]+=tag[o];
		tag[o]=0;
	}
}
int query(int o,int l,int r,int L,int R){
	if(L<=l&&r<=R)return mx[o];
	pushdown(o);
	int mid=(l+r)>>1,mx=-1e18;
	if(L<=mid)mx=max(mx,query(o*2,l,mid,L,R));
	if(R>mid)mx=max(mx,query(o*2+1,mid+1,r,L,R));
	return mx;
}
void update(int o,int l,int r,int L,int R,int val){
	if(L<=l&&r<=R){
		mx[o]+=val;
		tag[o]+=val;
		return;
	}
	pushdown(o);
	int mid=(l+r)>>1;
	if(L<=mid)update(o*2,l,mid,L,R,val);
	if(R>mid)update(o*2+1,mid+1,r,L,R,val);
	mx[o]=max(mx[o*2],mx[o*2+1]);
}
signed main(){
	scanf("%lld",&T);
	while(T--){
		scanf("%lld",&n);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
		for(int i=1;i<=4*n;i++)tag[i]=mx[i]=dp[i]=0;
		for(int i=n;i>=1;i--){
			if(i<n){
				dp[i]=max(query(1,1,n,i+1,min(i+a[i],n)),a[i]);
				update(1,1,n,i,i,dp[i]);
				update(1,1,n,i+1,n,a[i]);
			}
			else{
				dp[i]=a[i];
				update(1,1,n,i,i,dp[i]);
			}
		}
		printf("%lld\n",dp[1]);
	}
	return 0;
}
2024/4/29 10:14
加载中...