李超线段树

我视界里最不珂爱的 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;
}
posted @ 2023-08-12 22:51  Hypoxia571  阅读(13)  评论(0编辑  收藏  举报