bzoj4311 向量(線段樹分治 凸包)

2021-09-11 09:24:00 字數 3695 閱讀 7025

傳送門

題意:支援插入乙個向量,刪去某乙個現有的向量,查詢現有的所有向量與給出的乙個向量的點積的最大值。

思路:考慮線段樹分治。

先對於每個向量處理出其有效時間放到線段樹上面,然後考慮查詢:對於兩個已有的向量(u1

,v1)

(u_1,v_1)

(u1​,v

1​)和(u2

,v2)

(u_2,v_2)

(u2​,v

2​),假設給出的向量為(x0

,y0)

(x_0,y_0)

(x0​,y

0​)u

1>u2

&&(u

1,v1

)⋅(x

0,y0

)>(u

2,v2

)⋅(x

0,y0

)u_1>u_2\&\&(u_1,v_1)\cdot(x_0,y_0)>(u_2,v_2)\cdot(x_0,y_0)

u1​>u2

​&&(

u1​,

v1​)

⋅(x0

​,y0

​)>(u

2​,v

2​)⋅

(x0​

,y0​

)那麼展開得知:(u1

−u2)

x0

>−(

v1−v

2)y0

⇒−x0

y0

>v1

−v2u

1−u2

(u_1-u_2)x_0>-(v_1-v_2)y_0\rightarrow-\frac>\frac

(u1​−u

2​)x

0​>−(

v1​−

v2​)

y0​⇒

−y0​

x0​​

>u1

​−u2

​v1​

−v2​

​說明在凸包上,於是對於每個線段樹節點維護乙個凸包,查詢的時候在上面二分即可。

**:

#include

#define ri register int

#define fi first

#define se second

using

namespace std;

inline

intread()

typedef

long

long ll;

const

int n=

200005

;int n,tot1=

0,tot2=

0,q[n]

,top;

struct nodea[n]

;ll ans[n]

;struct pot

friend

inline pot operator+(

const pot&a,

const pot&b)

friend

inline pot operator-(

const pot&a,

const pot&b)

friend

inline ll operator^(

const pot&a,

const pot&b)

friend

inline ll operator*(

const pot&a,

const pot&b)

friend

inline

bool

operator

<

(const pot&a,

const pot&b)

}b[n]

;typedef pair<

int,pot> pii;

#define lc (p<<1)

#define rc (p<<1|1)

#define mid (l+r>>1)

vectorupd[n<<2]

;inline

void

update

(int p,

int l,

int r,

int ql,

int qr,pot v)

inline ll max

(const ll&a,

const ll&b)

inline ll max

(const ll&a,

const ll&b,

const ll&c)

inline

double

slope

(pot a,pot b)

inline ll query

(int p,pot tmp)

double slop=-(

double

)tmp.x/

(double

)tmp.y;

if(slop>

slope

(upd[p]

[q[2]]

,upd[p]

[q[1]]

))return tmp*upd[p]

[q[1]]

;if(slop<

slope

(upd[p]

[q[top]

],upd[p]

[q[top-1]

]))return tmp*upd[p]

[q[top]];

ret=

max(tmp*upd[p]

[q[1]]

,tmp*upd[p]

[q[top]])

;int l=

2,r=top,res=1;

while

(l<=r)

return tmp*upd[p]

[q[res]];

}inline

void

calc

(int p,

int l,

int r)

for(ri i=l;i<=r;

++i)ans[i]

=max

(ans[i]

,query

(p,b[i]))

;}inline

void

solve

(int p,

int l,

int r)

#undef lc

#undef rc

#undef mid

intmain()

;if(op==

2)a[

read()

].r=tot2;

if(op==

3)b[

++tot2]

.x=read()

,b[tot2]

.y=read()

;}for(ri i=

1;i<=tot1;

++i)

update(1

,1,tot2,a[i]

.l,~a[i]

.r?a[i]

.r:tot2,

pot(a[i]

.x,a[i]

.y))

;solve(1

,1,tot2)

;for

(ri i=

1;i<=tot2;

++i)cout<<<

'\n'

;return0;

}

BZOJ4311 向量(線段樹分治,斜率優化)

bzoj 先考慮對於給定的向量集,如何求解和當前向量的最大內積。設當前向量 x,y 有兩個不同的向量 u1,v1 u2,v2 並且 u1 u2 假設第乙個向量的結果優於第二個。xu1 yv1 xu2 yv2 移項可以得到 x u1 u2 y v2 v1 所以 x y v2 v1 u1 u2 也就是 ...

bzoj4311向量(線段樹分治 斜率優化)

第二道線段樹分治。首先設當前向量是 x,y 剩餘有兩個不同的向量 u1,v1 u2,v2 假設u1 u2,則移項可得,若 u1,v1 優於 u2,v2 則 x y v1 v2 u1 u2 然後維護上凸殼後進行三分即可,複雜度o nlog2n 如果將詢問排序掃一遍,可以優化到o nlogn 當然我沒寫...

線段樹分治

動態圖聯通性 可離線 loj121 給你一張無向圖,你要支援如下操作 1 刪除一條邊 2 加入一條邊 3 查詢某兩個點對間是否聯通 離線做法 線段樹分治 口胡做法 把操作的順序當做時間。每條邊維護乙個存活區間,代表這條邊在這個時間區間裡面活著。對時間軸建立一顆線段樹,從線段樹根開始dfs。進入乙個子...