线段树优化DP求调
  • 板块P1725 琪露诺
  • 楼主MvemiY
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/8/10 21:49
  • 上次更新2023/11/3 04:36:18
查看原帖
线段树优化DP求调
620253
MvemiY楼主2023/8/10 21:49
#include<bits/stdc++.h>
#define lc(x) x << 1
#define rc(x) x << 1 | 1
using namespace std;
const int MAXN = 2e5 + 5;
int n, L, R, a[MAXN], f[MAXN], ans = INT_MIN, SGT[4*MAXN], id[MAXN];
inline bool in(int tL, int tR, int l, int r){
	return l <= tL && tR <= r;
}
inline bool out(int tL, int tR, int l, int r){
	return l > tR || r < tL;
}
inline void pushup(int u){
	SGT[u] = max(SGT[lc(u)], SGT[rc(u)]);
}
void build(int u, int tL, int tR){
	if(tL == tR){
		SGT[u] = f[tL];
		id[tL] = u;
		return ;
	}
	int mid = (tL+tR) >> 1;
	build(lc(u), tL, mid);
	build(rc(u), mid+1, tR);
	pushup(u); 
}
void update(int x, int k){
	int u = id[x];
	SGT[u] = k;
	u >>= 1;
	while(u){
		pushup(u);
		u >>= 1;
	}
}
int query(int u, int tL, int tR, int l, int r){
	if(in(tL, tR, l, r))
		return SGT[u];
	if(out(tL, tR, l, r))
		return -0x3f3f3f3f;
	int mid = (tL+tR) >> 1;
	return max(query(lc(u), tL, mid, l, r), query(rc(u), mid+1, tR, l, r));
}
int main(){
	memset(f, -0x3f, sizeof(f));
	cin >> n >> L >> R;
	for(int i = 0; i <= n; i++)
		cin >> a[i];
	f[0] = 0;
	build(1, 0, n);
	for(int i = L; i <= n; i++){
		int k = query(1, 1, n, max(0, i-R), i-L);
		if(f[i] < k + a[i]){
			f[i] = k + a[i];
			update(i, k+a[i]);
		}
	}
	for(int i = n - R + 1; i <= n; i++)
		ans = max(ans, f[i]);
	cout << ans;
	return 0;
} 

用单调队列打完觉得可以用线段树做,但是爆灵(

有没有大佬知道哪里写挂了嘛

2023/8/10 21:49
加载中...