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 ...
随机推荐
- 使用Dbvisualizer 连接 Elasticsearch
Dbvisualizer 安装 从网上下载该软件,并破解激活 下载地址:http://www.ddooo.com/softdown/142713.htm 1.下载解压,得到dbvisualizer p ...
- APUE之第5章——标准I/O库
一.知识回顾:文件I/O 文件 I/O 是不带缓冲的 I/O(unbuffered I/O),指每个 read 和 write 都调用内核中的一个系统调用. 对于内核而言,所有打开的文件都通过文件描述 ...
- laravel 5.5 仓库模式 文件之间接口与实现操作
仓库模式 最直接的意思就是: Eloquent数据(数据库)查询 方便快捷,简单明了.自己怎么写的,就怎么去调用,完全ok~ 本质意思: 仓库就像是业务内部的数据对象集合,负责协调业务和数据映射层之 ...
- C# 创建json传输格式的http请求
public static string PostRequestTest(string content, string url, string contentType = "applicat ...
- httpclient cer
X509Certificate2 cer = new X509Certificate2(@"path", "********", X509KeyStorageF ...
- Appium中app的元素定位
app定位方式,本文只讲Android手机的定位方式. 前提条件是adb连接到模拟器或者是手机(具体连接方式这里不再讲解),证明已连接到设备 adb devices app元素定位工具一:UI Aut ...
- Ubuntu系统下容器化部署gitlab
容器化部署gitlab 获取镜像文件 1. 下载镜像文件 docker pull beginor/gitlab-ce:-ce. 2. 创建GitLab 的配置 (etc) . 日志 (log) .数据 ...
- pacman 命令详解
Pacman 是一个命令行工具,这意味着当你执行下面的命令时,必须在终端或控制台中进行. 1.更新系统 在 Arch Linux 中,使用一条命令即可对整个系统进行更新:pacman -Syu 如果你 ...
- JavaScript---js语法,数据类型及方法, 数组及方法,JSON对象及方法,日期Date及方法,正则及方法,数据类型转换,运算符, 控制流程(三元运算),函数(匿名函数,自调用函数)
day46 一丶javascript介绍 JavaScript的基础分为三个 1.ECMAScript:JavaScript的语法标准.包括变量,表达式,运算符,函数,if语句,for语句 ...
- 聊一下domain和entity
这段时间在负责海外事务,今天带着客户端走海外商店的支付流程.因为在国内接的大多数是渠道聚合的SDK,客户端就很少关注支付业务流程,只是按照以前的接的demo然后按照渠道提供的参数就直接上了.先po一张 ...
