李超线段树
我视界里最不珂爱的 SGT
代码我是真的自己写不动
所以这个是照着校 O勾 填空题目写的符合自己习惯的代码
我们要动态维护平面里的直线和诸如 \(x=t\) 这类直线的信息
大概原理不难理解
就是权值线段树对应区间维护的是当前区间的最优解
最优解指的是在这个区间里面最上面的线段
可以完全碾压别的线段那一种就算目前的最优解
是个强制在线的孩子,复杂度 \(O(n\log n)\) 酱紫,跟线段树一样
需要注意的是精度问题和一些计算几何的东西怎么好写且不寄
\(udt\) 笑死我了,校 O勾 代码寄了,重构力
#include<bits/stdc++.h>
#define MN 1010000
#define eps (1e-12)
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
using namespace std;
struct line {
double k, b;
} tr[MN<<2];
double calc(line a,int pos) { return a.k*(pos-1)+a.b; }
void modify(int p,int s,int e,line k) {
if(s==e) {
if(calc(tr[p],s)<calc(k,s)) tr[p]=k;
return;
}
int mid=(s+e)>>1;
if(tr[p].k>k.k) {
if(calc(k,mid)>calc(tr[p],mid))
modify(rs(p),mid+1,e,tr[p]), tr[p]=k;
else modify(ls(p),s,mid,k);
}
else {
if(calc(k,mid)>calc(tr[p],mid))
modify(ls(p),s,mid,tr[p]), tr[p]=k;
else modify(rs(p),mid+1,e,k);
}
}
double query(int p,int s,int e,int x) {
if(s==e) return calc(tr[p],x);
int mid=(s+e)>>1; double ans=0;
ans=calc(tr[p],x);
if(x<=mid) return max(ans,query(ls(p),s,mid,x));
else return max(ans,query(rs(p),mid+1,e,x));
}
int main() {
std::ios::sync_with_stdio(false);
int q; cin >> q;
for(int i=1; i<=q; ++i) {
string t;
cin >> t;
if(t=="Project") {
double s, p;
cin >> s >> p;
line now;
now.k=p, now.b=s;
modify(1,1,50000,now);
}
else {
int x; cin >> x;
int qwq=query(1,1,50000,x)/100;
printf("%d\n", max(qwq,0));
}
}
return 0;
}