传送门

题意:

支持插入一个向量,删去某一个现有的向量,查询现有的所有向量与给出的一个向量的点积的最大值。


思路:

考虑线段树分治。

先对于每个向量处理出其有效时间放到线段树上面,然后考虑查询:对于两个已有的向量(u1,v1)(u_1,v_1)(u1​,v1​)和(u2,v2)(u_2,v_2)(u2​,v2​),假设给出的向量为(x0,y0)(x_0,y_0)(x0​,y0​)u1>u2&&(u1,v1)⋅(x0,y0)>(u2,v2)⋅(x0,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​)>(u2​,v2​)⋅(x0​,y0​)

那么展开得知:(u1−u2)x0>−(v1−v2)y0⇒−x0y0>v1−v2u1−u2(u_1-u_2)x_0>-(v_1-v_2)y_0\Rightarrow-\frac{x_0}{y_0}>\frac{v_1-v_2}{u_1-u_2}(u1​−u2​)x0​>−(v1​−v2​)y0​⇒−y0​x0​​>u1​−u2​v1​−v2​​

说明在凸包上,于是对于每个线段树节点维护一个凸包,查询的时候在上面二分即可。

代码:

#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef long long ll;
const int N=200005;
int n,tot1=0,tot2=0,q[N],top;
struct Node{int l,r;ll x,y;}a[N];
ll ans[N];
struct pot{
	ll x,y;
	pot(ll _x=0,ll _y=0):x(_x),y(_y){}
	friend inline pot operator+(const pot&a,const pot&b){return pot(a.x+b.x,a.y+b.y);}
	friend inline pot operator-(const pot&a,const pot&b){return pot(a.x-b.x,a.y-b.y);}
	friend inline ll operator^(const pot&a,const pot&b){return a.x*b.y-a.y*b.x;}
	friend inline ll operator*(const pot&a,const pot&b){return a.x*b.x+a.y*b.y;}
	friend inline bool operator<(const pot&a,const pot&b){return a.x==b.x?a.y<b.y:a.x<b.x;}
}b[N];
typedef pair<int,pot> pii;
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
vector<pot>upd[N<<2];
inline void update(int p,int l,int r,int ql,int qr,pot v){
	if(ql>r||qr<l)return;
	if(ql<=l&&r<=qr)return upd[p].push_back(v);
	if(qr<=mid)update(lc,l,mid,ql,qr,v);
	else if(ql>mid)update(rc,mid+1,r,ql,qr,v);
	else update(lc,l,mid,ql,qr,v),update(rc,mid+1,r,ql,qr,v);
}
inline ll max(const ll&a,const ll&b){return a>b?a:b;}
inline ll max(const ll&a,const ll&b,const ll&c){return a>b?(a>c?a:c):(b>c?b:c);}
inline double slope(pot a,pot b){return a.x==b.x?1e9:(double)(a.y-b.y)/(double)(a.x-b.x);}
inline ll query(int p,pot tmp){
	ll ret=0;
	if(top<=3){
		for(ri i=1;i<=top;++i)ret=max(ret,tmp*upd[p][q[i]]);
		return ret;
	}
	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){
		int Mid=l+r>>1;
		if(slop<slope(upd[p][q[Mid]],upd[p][q[Mid-1]]))l=Mid+1,res=Mid;
		else r=Mid-1;
	}
	return tmp*upd[p][q[res]];
}
inline void calc(int p,int l,int r){
	if(!upd[p].size())return;
	sort(upd[p].begin(),upd[p].end());
	q[top=1]=0;
	for(ri i=1,up=upd[p].size()-1;i<=up;++i){
		while(top>1&&((upd[p][i]-upd[p][q[top-1]])^(upd[p][q[top]]-upd[p][q[top-1]]))<=0)--top;
		q[++top]=i;
	}
	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){
	calc(p,l,r);
	if(l==r)return;
	solve(lc,l,mid),solve(rc,mid+1,r);
}
#undef lc
#undef rc
#undef mid
int main(){
	n=read();
	for(ri op,x,y,i=1;i<=n;++i){
		op=read();
		if(op==1)x=read(),y=read(),a[++tot1]=(Node){tot2+1,-1,x,y};
		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<<ans[i]<<'\n';
	return 0;
}

2019.02.26 bzoj4311: 向量(线段树分治+凸包)的更多相关文章

  1. 【BZOJ4311】向量(线段树分治,斜率优化)

    [BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...

  2. [BZOJ4311]向量(凸包+三分+线段树分治)

    可以发现答案一定在所有向量终点形成的上凸壳上,于是在上凸壳上三分即可. 对于删除操作,相当于每个向量有一个作用区间,线段树分治即可.$O(n\log^2 n)$ 同时可以发现,当询问按斜率排序后,每个 ...

  3. BZOJ4311 向量(线段树分治+三分)

    由点积的几何意义(即投影)可以发现答案一定在凸壳上,并且投影的变化是一个单峰函数,可以三分.现在需要处理的只有删除操作,线段树分治即可. #include<iostream> #inclu ...

  4. bzoj4311向量(线段树分治+斜率优化)

    第二道线段树分治. 首先设当前向量是(x,y),剩余有两个不同的向量(u1,v1)(u2,v2),假设u1>u2,则移项可得,若(u1,v1)优于(u2,v2),则-x/y>(v1-v2) ...

  5. 2019.01.13 loj#6515. 贪玩蓝月(线段树分治+01背包)

    传送门 题意简述:有一个初始为空的双端队列,每次可以在队首和队尾插入或弹出一个二元组(wi,vi)(w_i,v_i)(wi​,vi​),支持询问从当前队列中选取若干个元素是的他们的和对 MODMODM ...

  6. 2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)

    传送门 题意:序列上有nnn个商店,有两种事件会发生: sss商店上进购标价为vvv的一个物品 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值 ...

  7. CF1442D Sum (动态规划,线段树分治)

    ( 宋 体 字 看 起 来 真 舒 服 ) _{_{(宋体字看起来真舒服)}} (宋体字看起来真舒服)​​ 题 面 ( 洛 谷 翻 译 ) 题面_{_{(洛谷翻译)}} 题面(洛谷翻译)​​ 给定 n ...

  8. loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)

    题意 题目链接 Sol 线性基+线段树分治板子题.. 调起来有点自闭.. #include<bits/stdc++.h> #define fi first #define se secon ...

  9. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

随机推荐

  1. Redis 服务端配置——Could not connect to Redis at 127.0.0.1:6379: Connection refused

    [root@centoszang 桌面]# redis-cli Could : Connection refused Could : Connection refused not connected& ...

  2. 实验一:通过bridge-utils工具创建网桥并实现网络连接

    实验名称: 通过bridge-utils工具创建网桥并实现网络连接 实验环境: 实验要求: 安装bridge-utils工具,创建网桥br0,通过brctl命令,为网桥配置IP地址192.168.23 ...

  3. Vue 目录结构 绑定数据 绑定属性 循环渲染数据

    一.目录结构分析 node_modules 项目所需要的各种依赖 src 开发用的资源 assets 静态资源文件 App.vue 根组件 main.js 配置路由时会用 .babelrc 配置文件 ...

  4. Maven CXF wsdl2Java List<Xxx>生成ArrayOfXxx包装对象 解决方法

    添加-xjc-Xxew解决,同时还要给插件添加相应的jar包,如下: <plugin> <groupId>org.apache.cxf</groupId> < ...

  5. shell文件测试,菜单表示思想

    ---恢复内容开始--- 文件测试表达式    -f 文件存在且为普通文件     -d 文件存在且为目录文件    -s 文件大小不为0则真    -e 文件存在则真        -r 文件存且可 ...

  6. PHP对接微信支付采坑

    第一次做PHP商城项目对接微信支付接口,踩了N次坑,这也不对,那也不对,搞了很久,查了一些资料,终于实现了支付功能,小小总结一下,万一下次遇到就不用到处找资料了. 微信扫码支付 前期准备: 1.微信公 ...

  7. GDI+_SavePic

    Option Explicit Private Const EncoderQuality As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB ...

  8. Mad Lids游戏 华氏与摄氏温度转换

    name1 = input('请输入一个名字:') name2 = input('请输入一个名字:') vehicle = input('请输入一种车子:') print('\n上近代史的{}刚下课, ...

  9. pip install 提示代理连接失败原因及解决办法

    # pip install 提示代理连接失败原因及解决办法 1. 错误提示 在公司电脑上安装Python的虚拟环境时输入命令: pip install virtualenv 系统提示以下异常信息: R ...

  10. 接口自动化测试链接https://www.cnblogs.com/finer/

    https://www.cnblogs.com/finer/ 测试框架的基本原则:业务逻辑与测试脚本分离,测试脚本与测试数据分离: 接口自动化的两种方式:工具(jmeter).代码(使用的是pytho ...