第二道線段樹分治。
首先設當前向量是(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<<1view code#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]);
}
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。進入乙個子...