求助李超线段树
查看原帖
求助李超线段树
430999
cjrqwq楼主2024/11/18 15:49

为什么开 44 倍空间 8080 分,要开 88 倍才能过。

写法是参考了日报的浅谈李超线段树的另一种实现方法

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int opt[N<<2];
// 要改成 N << 3
double x[N],a[N],bb[N],ra[N],rk[N];
double k[N],b[N];
#define mid ((l+r)/2)
double y(int i,int t) {
	return rk[i] * k[t] + b[t];
}
void upd(int u,int l,int r,int f) {
	int &g = opt[u];
	if(y(l,g) < y(l,f) && y(r,g) < y(r,f)) { g = f; return;}
	if(y(l,g) > y(l,f) && y(r,g) > y(r,f)) { return ;}
	upd(u*2,l,mid,f), upd(u*2+1,mid+1,r,f);
}
double qry(int u,int l,int r,int f) {
	if(l == r) return y(f,opt[u]);
	return max(y(f,opt[u]), f <= mid ? qry(u*2,l,mid,f) : qry(u*2+1,mid+1,r,f));
}
int n; double f;
int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	cin>>n>>f;
	for(int i=1;i<=n;i++) {
		cin>>a[i]>>bb[i]>>ra[i]; rk[i] = x[i] = 1.0*a[i]/bb[i];
	}
	sort(rk+1,rk+n+1);
	for(int i=1;i<=n;i++) {
		f = max(f,bb[i] * qry(1,1,n,lower_bound(rk+1,rk+n+1,x[i]) - rk));
		k[i] = f * ra[i] / (ra[i] * a[i] + bb[i]);
		b[i] = f / (ra[i] * a[i] + bb[i]);
		upd(1,1,n,i);
	}

	cout << fixed << setprecision(3) << f;
	return 0;
}
2024/11/18 15:49
加载中...