rt,AC之后我觉得题解的方法太抽象了,于是决定直接按照原始方程做 dp,但是不知道出了什么问题,有大佬可以帮忙看看吗%%%。
#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';
}
}