论这个题的鬼畜做法
查看原帖
论这个题的鬼畜做法
895690
gghack_Nythix楼主2024/5/2 12:34

rt,AC之后我觉得题解的方法太抽象了,于是决定直接按照原始方程做 dpdp,但是不知道出了什么问题,有大佬可以帮忙看看吗%%%。

#include<bits/stdc++.h>
#define int long long
#define lid (id << 1)
#define rid (id << 1 | 1)
using namespace std;
struct segt{
	int l,r;
	pair<int,int> val;
}tr[10000005];
int a[2000005];
void pushup(int id){
	if(tr[lid].val.second > tr[rid].val.second) tr[id].val = tr[lid].val;
	else tr[id].val = tr[rid].val;
	return ;
}
void build(int id,int l,int r){
	tr[id].l = l,tr[id].r = r;
	tr[id].val.first = tr[id].val.second = 0;
	if(l == r)return ;
	int mid = (l + r) >> 1;
	build(lid,l,mid),build(rid,mid + 1,r);
	pushup(id);
}
void cg(int id,int pos,int vall){
	if(tr[id].l == tr[id].r) {
		tr[id].val = make_pair(pos,vall);
		return ;
	}
	int mid = (tr[id].l + tr[id].r) >> 1;
	cg(pos <= mid?lid:rid,pos,vall);
}
pair<int,int> query(int id,int l,int r) {
	if(tr[id].l >= l && tr[id].r <= r) return tr[id].val;
	int mid = (tr[id].l + tr[id].r) >> 1;
	pair<int,int>ans = {-1,-1};
	if(l <= mid) {pair<int,int>tmp = query(lid,l,r);if(ans.second < tmp.second) ans = tmp;}
	if(r > mid) {pair<int,int>tmp = query(rid,l,r);if(ans.second < tmp.second) ans = tmp;}
	return ans;
}
int dp[2000005],sum[2000005];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin >> T;
	while(T-->0){
		memset(dp,-1,sizeof(dp));
		int n;
		cin >> n;
		build(1,1,n);
		for(int i = 1;i <= n;++i) cin >> a[i];
		for(int i = 1;i <= n;++i) sum[i] = sum[i - 1] + a[i];
		for(int i = n;i >= 1;--i) {
			dp[i] =	a[i];
			int l = i + 1,r = min(i + a[i],n);
			pair<int,int> tmp = query(1,l,r);
			dp[i] = max(dp[i],tmp.second + sum[i + tmp.first - 1] - sum[l - 1]);
			cg(1,i,dp[i]);
		}
		cout << dp[1] << '\n';
	}
}
2024/5/2 12:34
加载中...