[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. k8s-架构中各个组件介绍

    参考链接:https://github.com/opsnull/follow-me-install-kubernetes-cluster kubernetes 概述 1.kubernetes 是什么 ...

  2. framework7 总结之前遇到的问题和踩过的坑

    官网上写的案例比较简单明了,我这里就将我使用时踩过的坑做一个总结,与大家共勉! 最近使用framework,基本全靠浏览官方文档,当然,有遇到了许多的错误,开始不知道哪里出问题也很着急,到最后发现问题 ...

  3. jQuery中cookie的简单操作

    jQuery 可以通过 jquery.cookie.js 插件来操作 Cookie. 用NuGet安装:PM>Install-Package js-cookie -Version 官网:http ...

  4. Schnorr签名介绍

    Schnorr签名介绍 来源 https://panzhibiao.com/2019/02/28/schnorr-sigature/ https://github.com/bitcoin/bitcoi ...

  5. Linux环境下:vmware安装Windows报错误-缺少所需的CD/DVD驱动器设备驱动程序

    解决方法:将硬盘格式从SCSI改为IDE. 方法如下: 右键点击你新建的虚拟机名,点击最下面的setting,看到左侧第二行是hard disk 了么,你那里肯定是SCSI的,选中它,点最下面的rem ...

  6. Java自学-接口与继承 UML图

    UML 图 步骤 1 : UML 图 -- 类之间的关系 UML-Unified Module Language 统一建模语言,可以很方便的用于描述类的属性,方法,以及类和类之间的关系 步骤 2 : ...

  7. 【Kafka】Exactly Once语义与事务

    Kafka在0.11.0.0之前的版本中只支持At Least Once和At Most Once语义,尚不支持Exactly Once语义. 但是在很多要求严格的场景下,如使用Kafka处理交易数据 ...

  8. Vue学习之路由vue-router传参及嵌套小结(十)

    一.路由传递参数: 1.使用query传值: <!DOCTYPE html> <html lang="en"> <head> <meta ...

  9. Map去重,去重value相同的元素,保留key最小的那个值

    Map<Integer,String>,Integer代表时间撮,String代表文本信息去重函数:就是删除Map中value相同的元素,只保留key最小的那个元素 public stat ...

  10. Jvm调优积累的文章

    Linux查看CPU和内存使用情况 stat命令查看jvm的GC情况 (以Linux为例) jvm优化必知系列——监控工具 Java JVM 参数设置大全