Vue常用特性-計算屬性computed 和 偵聽器 watch
阿新 • • 發佈:2020-11-30
前言
T4正解李超線段樹?不會,滾過來學
保留節目百度百科自學已被刪除
講解
貌似思路並不是很難的亞子
我們需要線上支援一下兩個操作:
-
插入一條線段
-
給定\(x_0\),詢問當\(x=x_0\)時所有線段的最高點
我們可以使用權值線段樹!
對於每個區間,我們維護一個最優線段
1.插入
顯然對於一個線段完全覆蓋的區間我們才處理
分四種情況討論:
(1).當前區間無最優線段
直接賦值
(2).當前線段完全覆蓋最優線段
直接賦值
(3).當前線段完全被最優線段覆蓋
直接滾粗
(4).相交
最複雜的情況,我們考慮將覆蓋該區間最長的線段保留為最優線段
欸嘿?怎麼搞呢?其實只需判斷該區間中點誰在上面就行了,中點位置在上面的線段一定是覆蓋最長的線段
然後把另外一條丟到下面去接著修改
插入時間複雜度\(O(\log^2 n)\)
2.詢問
一直往下走,對於每個走到的區間的最優線段求出一個函式值,取\(\texttt{max}\)即可
詢問時間複雜度\(O(\log n)\)
練習
程式碼
「雅禮集訓 2017 Day2」線段遊戲
const int M = 1000001; const int MAXN = 2000005; int n,Q; struct line { double k,b; bool f; line(){} line(double k1,double b1,bool f1){ k = k1; b = b1; f = f1; } }; #define lc (x<<1) #define rc (x<<1|1) double getf(line w,int x){return w.k * x + w.b;} struct LiChaoSegmentTree { line t[MAXN << 2]; void Add(int x,int l,int r,int ql,int qr,line w) { int mid = (l+r) >> 1; if(ql <= l && r <= qr) { if(!t[x].f) t[x] = w; else if(getf(w,l) >= getf(t[x],l) && getf(w,r) >= getf(t[x],r)) t[x] = w; else if(getf(w,l) <= getf(t[x],l) && getf(w,r) <= getf(t[x],r)) return; else { if(getf(w,mid) >= getf(t[x],mid)) swap(w,t[x]); if(getf(w,l) > getf(t[x],l)) Add(lc,l,mid,ql,qr,w); else Add(rc,mid+1,r,ql,qr,w); } return; } if(ql <= mid) Add(lc,l,mid,ql,qr,w); if(mid+1 <= qr) Add(rc,mid+1,r,ql,qr,w); } double Query(int x,int l,int r,int q) { double ret = -M; if(l <= q && q <= r && t[x].f) ret = getf(t[x],q); if(l == r) return ret; int mid = (l+r) >> 1; if(q <= mid) ret = Max(ret,Query(lc,l,mid,q)); else ret = Max(ret,Query(rc,mid+1,r,q)); return ret; } }st; void AddLine() { int x1 = Read() + M,y1 = Read(),x2 = Read() + M,y2 = Read(); double k,b; if(x1 == x2) k = 0,b = Max(y1,y2); else k = 1.0 * (y2-y1) / (x2-x1),b = y1 - k * x1; st.Add(1,1,M<<1,Min(x1,x2),Max(x1,x2),line(k,b,1)); } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); n = Read(); Q = Read(); for(int i = 1;i <= n;++ i) AddLine(); for(; Q ;-- Q) { int opt = Read(); if(!opt) AddLine(); else { double ans = st.Query(1,1,M<<1,Read()+M); if(ans == -M) Put(0,'\n'); else printf("%.2f\n",ans); } } return 0; }