李超树 94pt WA 最后一个点 求条
查看原帖
李超树 94pt WA 最后一个点 求条
431658
冷却心月明かり楼主2024/8/17 23:25

使用动态开点李超树。码风良好。

#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
const int N = 5e5 + 10;
const LL M = 1e12;
int n;
long long m, X[N], R[N], V[N];
long double F[N];

struct LnF { long double k, b; } l[N];
const long double eps = 1e-9;
int cmp(long double a, long double b) {
	if (a - b > eps) return 1;
	if (b - a > eps) return -1;
	return 0;
}
long double Calc(LL x, LL c) { return (!c ? 1e9 : l[c].k * x + l[c].b); } 

int tree[N * 30], ls[N * 30], rs[N * 30], tot = 0, rt = 0;
void update(int &p, LL l, LL r, int u) {
	if (!p) p = ++ tot;
	int &v = tree[p]; LL mid = (l + r) >> 1;
	int fm = cmp(Calc(mid, u), Calc(mid, v));
	if (fm == -1 || (!fm && u < v)) swap(u, v);
	int fl = cmp(Calc(l, u), Calc(l, v));
	int fr = cmp(Calc(r, u), Calc(r, v));
	if (fl == -1 || (!fl && u < v)) update(ls[p], l, mid, u);
	if (fr == -1 || (!fr && u < v)) update(rs[p], mid + 1, r, u);
}

long double query(int &p, LL l, LL r, int x) {
	if (!p || x > r || x < l) return 1e9;
	LL mid = (l + r) >> 1;
	return min(Calc(x, tree[p]), min(query(ls[p], l, mid, x), query(rs[p], mid + 1, r, x)));
}

void AddSgt(long double k, long double b) {
	l[++ tot] = {k, b};
	update(rt, 1, M, tot);
}

int main() {
	ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i ++) {
		cin >> X[i] >> R[i] >> V[i];
	}
	F[1] = V[1]; AddSgt((long double)1 / 2 / sqrtl(R[1]), -(long double)X[1] / 2 / sqrtl(R[1]) + F[1]);
	for (int i = 2; i <= n; i ++) {
		F[i] = query(rt, 1, M, X[i]) + V[i];
		AddSgt((long double)1 / 2 / sqrtl(R[i]), -(long double)X[i] / 2 / sqrtl(R[i]) + F[i]);
	}
	long double Ans = 1e18;
	for (int i = 1; i <= n; i ++) {
		if (X[i] + R[i] >= m) {
			Ans = min(Ans, F[i]);
		}
	}
	cout << fixed << setprecision(3) << Ans << "\n";
	return 0;
}
2024/8/17 23:25
加载中...