帮帮可怜的孩子吧!
查看原帖
帮帮可怜的孩子吧!
67817
MuYC楼主2021/6/5 15:09

我的做法大致思路是这样:

现在考虑定一个右端点 nowrnowr,定义线段树中节点 [l,l][l,l] 表示的是区间 [l,nowr][l,nowr] 的答案。

每次右移的时候相当于插入一个 (dnowr+1dnowr)2(d_{nowr + 1} - d_{nowr})^2并且对于每一个 11 ~ nowrnowr 的对应答案点的答案加上 aP[nowr+1].ca - P[nowr + 1].c

固定右端点的情况下,越往左边则 maxi=li=nowr1(di+1di)2\displaystyle \max_{i = l}^{i = nowr-1}(d_{i+1}-d_i)^2 越小,于是可以在线段树上二分,动态维护答案最大值。

但是本辣鸡一直 WAWA onon testtest 77

希望有大佬告诉我这个方法的错误或者代码的错误,亦或者是提供一下 HackHack 数据,感激不尽!

Code

#include <bits/stdc++.h>
using namespace std;
#define ls (x << 1)
#define rs (x << 1 | 1)
#define mid ((T[x].l + T[x].r) >> 1)
#define int long long
inline int read() {
	int x = 0, flag = 1;
	char ch = getchar();
	for( ; ch > '9' || ch < '0' ; ch = getchar()) if(ch == '-') flag = -1;
	for( ; ch >= '0' && ch <= '9' ; ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
	return x * flag;
}
int sqr(int a) { return 1ll * a * a ; }
const int MAXN = 3e5 + 50;
int n, V, m;
int Ans = 0;
struct Point {
	int c, d;
} P[MAXN];

struct SegmentTree {
	int l, r, Dmax, Dmin, Max, taga, tagb;
} T[MAXN << 2];
void update(int x) {
	T[x].Max = max(T[ls].Max, T[rs].Max);
	T[x].Dmax = max(T[ls].Dmax, T[rs].Dmax);
	T[x].Dmin = min(T[ls].Dmin, T[rs].Dmin);
}

void build(int x, int l, int r) {
	T[x].l = l, T[x].r = r, T[x].taga = T[x].tagb = 0;
	if(l == r) return ;
	build(ls, l, mid), build(rs, mid + 1, r);
	return ;
}

void ad(int x, int M, int Add) {
	T[x].Max += Add; 
	if(M >= T[x].Dmax) {
		T[x].Max -= (sqr(M) - sqr(T[x].Dmax));
		T[x].Dmin = T[x].Dmax = T[x].taga = M;
	}
	T[x].tagb += Add;
	return ;
}

void pushdown(int x) {
	ad(ls, T[x].taga, T[x].tagb);
	ad(rs, T[x].taga, T[x].tagb);
	T[x].taga = T[x].tagb = 0;
}

void change(int x, int l, int r, int k, int w) { 
	if(T[x].l >= l && T[x].r <= r) { ad(x, k, w); return ; }
	pushdown(x);
	if(l <= mid) change(ls, l, r, k, w);
	if(r >  mid) change(rs, l, r, k, w);
	update(x);
}

void modify(int x, int l, int r, int k) {
	if(l > r) return ;
	if(T[x].l >= l && T[x].r <= r) {
		if(T[x].Dmax <= k) { ad(x, k, 0); return ; }
		if(T[x].l == T[x].r) return ;
		pushdown(x);
		if(k < T[x].Dmin) return ;
		modify(ls, l, r, k), modify(rs, l, r, k), update(x);
		return ;
	}
	pushdown(x);
	if(l <= mid) modify(ls, l, r, k);
	if(r  > mid) modify(rs, l, r, k);
	update(x);
	return ;
}

signed main() {
	n = read(), V = read(), build(1, 1, n);
	for(int i = 1 ; i <= n ; i ++) P[i].d = read(), P[i].c = V - read();
	for(int i = 1; i <= n ; i ++) {
		change(1, 1, i, 0, P[i].c);
		modify(1, 1, i - 1, P[i].d - P[i - 1].d);
		Ans = max(Ans, T[1].Max);
	}
	cout << Ans;
	return 0;
}
2021/6/5 15:09
加载中...