SDOI 2014 向量集
[SDOI2014]向量集
题目描述
输入输出格式
输入格式
输出格式
输入输出样例
输入样例 #1
6 A
A 3 2
Q 1 5 1 1
A 15 14
A 12 9
Q 12 8 12 15
Q 21 18 19 18
输出样例 #1
13
17
17
说明
[题意]
维护向量序列,支持在序列末尾添加向量,以及询问某个区间中的向量与给定向量的点积的最大值。
[官方题解]

[个人题解](网上东拼西凑的)
一般性设当前询问的$y_0>0$,那么$\dfrac{ans}{y_0}=\max\{\dfrac{x_0}{y_0}\cdot x+y\}$,然后这个东西和斜率优化长得一样,答案一定是在凸壳上的.
于是我们维护这个凸壳.因为有区间询问所以线段树维护每个区间的凸壳.具体地,插入的时候统计当前区间已经有多少个点,如果点数等于当前区间长度那么构造出这个区间的凸壳.询问的时候拆成$\log$个区间分别跑二分/三分即可.
求凸包这里使用按$x$坐标排序的那个算法.注意如果几个点的$x$相同那么要按$y$排序.
插入的时候每个区间只会被构建一次凸包,总复杂度$O(n\log n)$,排序用归并.
查询的时候拆成$\log$个区间,每个区间$O(\log n)$三分/二分,总复杂度$O(n\log ^2 n)$
每个区间都要构建一次凸包,可以这么处理:每个线段树节点放个指针,动态开辟空间建立凸包。
网上不少代码把情况讨论合并成一种,只维护上凸壳。保险起见,也为了自己能够更好地理解,我还是分类讨论,同时维护上下凸壳。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
register char ch=getchar();x=;register bool f=;
for(;ch<''||ch>'';ch=getchar()) if(ch=='-') f=;
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-'';
if(f) x=-x;
}
const int N=4e5+;
int n,m,cnt;ll ans;char type[],op[];
struct Q{
int opt,l,r,x,y;
Q(){}
Q(int opt,int l,int r,int x,int y):opt(opt),l(l),r(r),x(x),y(y){}
}q[N];
struct point{
int x,y;
point(int x=,int y=):x(x),y(y){}
point operator +(const point &a)const{
return point(x+a.x,y+a.y);
}
point operator -(const point &a)const{
return point(x-a.x,y-a.y);
}
ll operator *(const point &a)const{
return (ll)x*a.x+(ll)y*a.y;
}
ll operator ^(const point &a){
return (ll)x*a.y-(ll)y*a.x;
}
bool operator <(const point &a)const{
return x==a.x?y<a.y:x<a.x;
}
}p[N],tmp[N];int tmpsize;
struct CH{
point *up,*dw;
int upsize,dwsize;
void init(int l,int r){
up=new point[r-l+];
dw=new point[r-l+];
tmpsize=upsize=dwsize=;
for(int i=l;i<=r;i++) tmp[++tmpsize]=p[i];
sort(tmp+,tmp+tmpsize+);
for(int i=;i<=tmpsize;i++){
for(;upsize>&&((tmp[i]-up[upsize])^(up[upsize]-up[upsize-]))<=;upsize--);
up[++upsize]=tmp[i];
for(;dwsize>&&((dw[dwsize]-dw[dwsize-])^(tmp[i]-dw[dwsize]))<=;dwsize--);
dw[++dwsize]=tmp[i];
}
}
ll qmax(point p){
int l,r,mid1,mid2;ll res=-(1LL<<);
if(p.y>=){
l=;r=upsize;
while(r-l>){
mid1=l+(r-l)/;
mid2=r-(r-l)/;
if(up[mid1]*p<up[mid2]*p)
l=mid1;
else
r=mid2;
}
for(int i=l;i<=r;i++) res=max(res,up[i]*p);
}
else{
l=;r=dwsize;
while(r-l>){
mid1=l+(r-l)/;
mid2=r-(r-l)/;
if(dw[mid1]*p<dw[mid2]*p)
l=mid1;
else
r=mid2;
}
for(int i=l;i<=r;i++) res=max(res,dw[i]*p);
}
return res;
}
}b[N<<];bool tag[N<<];
#define lch k<<1
#define rch k<<1|1
ll query(int k,int l,int r,int x,int y,point p){
if(l==x&&r==y){
if(!tag[k]) tag[k]=,b[k].init(l,r);
return b[k].qmax(p);
}
int mid=l+r>>;
if(y<=mid) return query(lch,l,mid,x,y,p);
else if(x>mid) return query(rch,mid+,r,x,y,p);
else return max(query(lch,l,mid,x,mid,p),query(rch,mid+,r,mid+,y,p));
}
inline void decode(int &x){
if(type[]=='E') return ;
x=x^(ans&0x7fffffff);
}
int main(){
read(m);scanf("%s",type);
for(int i=,opt,x,y,l,r;i<=m;i++){
scanf("%s",op);opt=(op[]=='Q');
if(opt){
read(x);read(y);
read(l);read(r);
}
else{
read(x);read(y);l=r=;
++n;
}
q[i]=Q(opt,l,r,x,y);
}
for(int i=,l,r,x,y;i<=m;i++){
if(q[i].opt){
l=q[i].l;r=q[i].r;
x=q[i].x;y=q[i].y;
decode(l);decode(r);
decode(x);decode(y);
ans=query(,,n,l,r,point(x,y));
printf("%lld\n",ans);
}
else{
x=q[i].x;y=q[i].y;
decode(x);decode(y);
p[++cnt]=point(x,y);
}
}
return ;
}
收获:
所有形如$f[i]=\min\limits_{L(i)\leq j\leq R(i)}\{k(i)x(j)+F(j)\}+G(i)$的$dp$都是可做的(斜率优化型动态规划)
SDOI 2014 向量集的更多相关文章
- BZOJ 3533 sdoi 2014 向量集
设(x,y)为Q的查询点,分类讨论如下:1.y>0: 最大化a*x+b*y,维护一个上凸壳三分即可 2.y<0:最大化a*x+b*y 维护一个下凸壳三分即可 我们考虑对时间建出一棵线段 ...
- BZOJ 3533: [Sdoi2014]向量集( 线段树 + 三分 )
答案一定是在凸壳上的(y>0上凸壳, y<0下凸壳). 线段树维护, 至多N次询问, 每次询问影响O(logN)数量级的线段树结点, 每个结点O(logN)暴力建凸壳, 然后O(logN) ...
- 【SDOI2014】向量集
[SDOI2014]向量集 题目描述 我们分析一波: 假设我们询问\((A,B)\),\(x_i>x_j\)若 \[ A\cdot x_i+B\cdot y_i>A\cdot x_j+B\ ...
- 「SDOI2014」向量集 解题报告
「SDOI2014」向量集 维护一个向量集合,在线支持以下操作: A x y :加入向量 \((x, y)\): Q x y l r:询问第 \(L\) 个到第 \(R\) 个加入的向量与向量 \(( ...
- BZOJ3533 [Sdoi2014]向量集 【线段树 + 凸包 + 三分】
题目链接 BZOJ3533 题解 我们设询问的向量为\((x_0,y_0)\),参与乘积的向量为\((x,y)\) 则有 \[ \begin{aligned} ans &= x_0x + y_ ...
- Spark Mllib里的本地向量集(密集型数据集和稀疏型数据集概念、构成)(图文详解)
不多说,直接上干货! Local vector : 本地向量集 由两类构成:稀疏型数据集(spares)和密集型数据集(dense) (1).密集型数据集 例如一个向量数据(9,5,2,7),可以设 ...
- bzoj3533: [Sdoi2014]向量集
Description 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);" Q x y l r (|x| ...
- BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)
Description 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); " Q x y l r (| ...
- bzoj3533【Sdoi2014】向量集
题目描述 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);" Q x y l r (|x|,|y| &l ...
随机推荐
- - Permission 运行时权限 总结 翻译 MD
目录 目录 对运行时权限的一些理解 运行时权限使用案例 开源库:PermissionsDispatcher 注解 使用案例 使用步骤 测试代码 自动生成的类 官方文档:请求权限 Add permiss ...
- -Shell 命令行工具 Cmder Babun Zsh MD
目录 目录 Cmder:window 下增强型的 cmd + bash 简介 配置 解决中文乱码问题 添加到右键菜单 添加至环境变量 修改命令提示符号 自定义aliases Readme.md 设置c ...
- 将EntityFrameworkCore生成的SQL语句输出到控制台,使用hangfire
将EntityFrameworkCore生成的SQL语句输出到控制台 参考文档如下 EF Core 日志记录要求使用一个或多个日志记录提供程序配置的 ILoggerFactory. 日志记录-EF C ...
- Ablation Study
We often come across 'ablation study' in machine learning papers, for example, in this paper with th ...
- Django(二)模板
一.模板概念 1.Django通过模板动态生成html 2.模板的加载位置 模板一般建立在templates文件夹中,全局路径的设置在settings.py中 DIRS:决定了整个项目的模板路径的 ...
- drf--ModelSerializers序列化
目录 drf--ModelSerializers序列化 项目准备 配置 settings.py 路由 多表设计 表关系分析 创建models 模型序列化 自定义模型序列化 api/serializer ...
- 第一次Git上传本地项目到github上 的命令
1.下载Git软件:https://git-scm.com/downloads, 2.下载之后安装就很简单了, 3.邮箱注册 在git bash界面输入如下内容即可完成邮箱的注册: $ git con ...
- python数据分析三剑客之: pandas操作
pandas的操作 pandas的拼接操作 # pandas的拼接操作 级联 pd.concat , pd.append 合并 pd.merge , pd.join 一丶pd.concat()级联 # ...
- localStorage、sessionStorage、Cookie的区别及用法
1.webstorage 本地存储,存储在客户端,包括localStorage和sessionStorage. (1)localStorage:生命周期是永久,这意味着除非用户显示在浏览器提供的UI上 ...
- Jest单元测试进阶
Jest 命令行窗口中的指令 在学习Jest单元测试入门的时候,给Jest命令提供了一个参数 --watchAll, 让它监听测试文件或测试文件引入的文件的变化,从而时时进行测试.但这样做也带来一个问 ...
