[SDOI2014]向量集

题目描述

维护一个向量集合,在线支持以下操作: - "A x y (|x|,|y| < =10^8)":加入向量(x,y); - " Q x y l r (|x|,|y| < =10^8,1 < =L < =R < =T,其中T为已经加入的向量个数)询问第L个到第R个加入的向量与向量(x,y)的点积的最大值。 集合初始时为空。

输入输出格式

输入格式

输入的第一行包含整数N和字符s,分别表示操作数和数据类别; 接下来N行,每行一个操作,格式如上所述。 请注意s≠'E'时,输入中的所有整数都经过了加密。你可以使用以下程序得到原始输入: ··· inline int decode (int x long long lastans) { return x ^ (lastans & Ox7fffffff); } ``` 其中x为程序读入的数,lastans为之前最后一次询问的答案。在第一次询问之前,lastans=0。注:向量(x,y)和(z,W)的点积定义为xz+yw。

输出格式

对每个Q操作,输出一个整数表示答案。

输入输出样例

输入样例 #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

说明

样例解释:解密之后的输入为 ``` 6 E A 3 2 Q 1 5 1 1 A 2 3 A 1 4 Q 1 5 1 2 Q 4 3 2 3 ``` 1 < =N < =4\*10^5

[题意]

维护向量序列,支持在序列末尾添加向量,以及询问某个区间中的向量与给定向量的点积的最大值。

[官方题解]

[个人题解](网上东拼西凑的)


一般性设当前询问的$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 向量集的更多相关文章

  1. BZOJ 3533 sdoi 2014 向量集

    设(x,y)为Q的查询点,分类讨论如下:1.y>0:  最大化a*x+b*y,维护一个上凸壳三分即可 2.y<0:最大化a*x+b*y  维护一个下凸壳三分即可 我们考虑对时间建出一棵线段 ...

  2. BZOJ 3533: [Sdoi2014]向量集( 线段树 + 三分 )

    答案一定是在凸壳上的(y>0上凸壳, y<0下凸壳). 线段树维护, 至多N次询问, 每次询问影响O(logN)数量级的线段树结点, 每个结点O(logN)暴力建凸壳, 然后O(logN) ...

  3. 【SDOI2014】向量集

    [SDOI2014]向量集 题目描述 我们分析一波: 假设我们询问\((A,B)\),\(x_i>x_j\)若 \[ A\cdot x_i+B\cdot y_i>A\cdot x_j+B\ ...

  4. 「SDOI2014」向量集 解题报告

    「SDOI2014」向量集 维护一个向量集合,在线支持以下操作: A x y :加入向量 \((x, y)\): Q x y l r:询问第 \(L\) 个到第 \(R\) 个加入的向量与向量 \(( ...

  5. BZOJ3533 [Sdoi2014]向量集 【线段树 + 凸包 + 三分】

    题目链接 BZOJ3533 题解 我们设询问的向量为\((x_0,y_0)\),参与乘积的向量为\((x,y)\) 则有 \[ \begin{aligned} ans &= x_0x + y_ ...

  6. Spark Mllib里的本地向量集(密集型数据集和稀疏型数据集概念、构成)(图文详解)

    不多说,直接上干货! Local  vector : 本地向量集 由两类构成:稀疏型数据集(spares)和密集型数据集(dense) (1).密集型数据集 例如一个向量数据(9,5,2,7),可以设 ...

  7. bzoj3533: [Sdoi2014]向量集

    Description 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);" Q x y l r (|x| ...

  8. BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)

    Description 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); " Q x y l r (| ...

  9. bzoj3533【Sdoi2014】向量集

    题目描述 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);" Q x y l r (|x|,|y| &l ...

随机推荐

  1. 大数据技术 - 为什么是SQL

    在大数据处理以及分析中 SQL 的普及率非常高,几乎是每一个大数据工程师必须掌握的语言,甚至非数据处理岗位的人也在学习使用 SQL.今天这篇文章就聊聊 SQL 在数据分析中作用以及掌握 SQL 的必要 ...

  2. Spring Cloud之Zuul网关路由

    前端请求先通过nginx走到zuul网关服务,zuul负责路由转发.请求过滤等网关接入层的功能,默认和ribbon整合实现了负载均衡 比如说你有20个服务,暴露出去,你的调用方,如果要跟20个服务打交 ...

  3. (转)二步实现 远程连接 阿里云SqlServer 2012 数据库服务器

    前言:在使用 阿里云 上的一些产品时,遇到不少坑. 安装IIS 时,遇到 因买的配置过低,虚拟内存不足,而导致 IIS 总是安装失败: 现在 在上面安装了个 Sql Sever 2012,远程老是 不 ...

  4. 如何在pycharm中设置环境变量

    今天运行tensorflow的时候,发现在pycharm下,程序无法找到CUDA的libcupti.so文件.而在添加完环境变量: export LD_LIBRARY_PATH=$LD_LIBRARY ...

  5. SQL Server 2017 下载及安装详细教程

    SQL Servicer 2017 下载及安装 1)下载安装SQLServer 2)安装SQLServer management Studio. 一.     下载及安装SQLServer 下载链接( ...

  6. Vue相关知识点记录

    1.安装 vue不支持ie8以下版本(无法模拟ECMAScript5特性),支持所有兼容ECMAScript5的浏览器. 浏览器安装Vue Devtools, 可以在更友好的界面中审查和调试Vue应用 ...

  7. 【总结】web工作代码分类整理(持续更新)

    文件.blob 文件下载失败,将Blob对象转换为Json,处理异常错误? 使用FileReader,核心代码: var reader = new FileReader() reader.onload ...

  8. IOS基础:Objective-C 字符串处理

    //一.NSString/*----------------创建字符串的方法----------------*/ //1.创建常量字符串.NSString *astring = @"This ...

  9. sqlserver一次性修改多条

    修改客户表 编号为 0101007002,0101007003的楼栋号  007-1-102,007-1-201 UPDATE gas_customerSET building= CASEWHEN g ...

  10. Httpd服务入门知识-Httpd服务常见配置案例之Apache的工作做状态status页面

    Httpd服务入门知识-Httpd服务常见配置案例之Apache的工作做状态status页面 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.status功能概述 status页 ...