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

2022-05-05 12:36:07 字數 1449 閱讀 8146

第二道線段樹分治。

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

#include#define lson l,mid,rt<<1

#define rson mid+1,r,rt<<1|1

using

namespace

std;

typedef

long

long

ll;const

int n=2e5+7

;struct nodep[n],q[n];

intn,tim,tot,top;

ll ans[n];

vector

a[n<<2

];node st[n];

bool cmp(node a,node b)

ll dot(node a,node b)

ll cross(node a,node b,node c)

void update(int l,int r,int id,int l,int r,int

rt)

int mid=l+r>>1

;

if(l<=mid)update(l,r,id,lson);

if(r>mid)update(l,r,id,rson);

}ll query(

intid)

for(int i=l;i<=r;i++)ret=max(ret,dot(q[id],st[i]));

return

ret;

}void work(int x,int l,int

r)

for(int i=l;i<=r;i++)ans[i]=max(ans[i],query(i));

}void divide(int l,int r,int

rt)int

main()

;

else

if(op==2)p[x].r=tim;

else scanf("

%d",&y),q[++tim]=(node);

}for(int i=1;i<=tot;i++)if(p[i].r==-1)p[i].r=tim;

for(int i=1;i<=tot;i++)if(p[i].l<=p[i].r)update(p[i].l,p[i].r,i,1,tim,1

); divide(

1,tim,1

);

for(int i=1;i<=tim;i++)printf("

%lld\n

",ans[i]);

}

view code

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

傳送門 題意 支援插入乙個向量,刪去某乙個現有的向量,查詢現有的所有向量與給出的乙個向量的點積的最大值。思路 考慮線段樹分治。先對於每個向量處理出其有效時間放到線段樹上面,然後考慮查詢 對於兩個已有的向量 u1 v1 u 1,v 1 u1 v 1 和 u2 v2 u 2,v 2 u2 v 2 假設給...

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 也就是 ...

線段樹分治

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