【bzoj3533】[Sdoi2014]向量集 线段树+STL-vector维护凸包
题目描述
维护一个向量集合,在线支持以下操作:
"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操作,输出一个整数表示答案。
样例输入
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
样例输出
13
17
17
题解
线段树+STL-vector维护凸包
本质是什么呢:给出 $x_0$ 和 $y_0$ ,求满足条件的 $x,y$ 使得 $x_0x+y_0y$ 最大。
我们不妨设这个值是 $c$ ,则要最大化 $c$ 。
当 $y>0$ 时:
给这个式子 $c=x_0x+y_0y$ 变形,得:$y=-\frac {x_0}{y_0}x+\frac c{y_0}$ 。想要 $c$ 最大,即要 $\frac c{y_0}$ 最大。
相当于是一条斜率为 $-\frac{x_0}{y_0}$ 的直线,要使纵截距最大,答案一定在上凸壳上,且所选点与答案形成单峰函数。
因此维护上凸壳,在凸壳上二分即可。
$y<0$ 的情况同理,维护下凸壳并二分即可。$y=0$ 的情况只要求 $x$ 最大/小,在两个凸壳上二分都可以。
考虑使用线段树维护一段区间的凸壳。
由于强制在线,因此不能提前求凸壳。但我们可以发现:如果线段树的一个节点没有被全部加入(即没加全),那么这个点一定不会出现在询问区间中。因此我们在线段树上插入,当且仅当 $tot==r$ 时,对该节点建立上凸壳即可。
时间复杂度 $O(n\log^2 n)$
#include <cstdio>
#include <vector>
#include <algorithm>
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
typedef long long ll;
struct point
{
ll x , y;
point() {}
point(ll a , ll b) {x = a , y = b;}
ll operator*(const point &a)const {return x * a.x + y * a.y;}
ll operator^(const point &a)const {return x * a.y - y * a.x;}
point operator-(const point &a)const {return point(x - a.x , y - a.y);}
bool operator<(const point &a)const {return x == a.x ? y < a.y : x < a.x;}
};
vector<point> t[1600010] , v1[1600010] , v2[1600010];
char opt[5] , str[5];
void insert(int p , point o , int l , int r , int x)
{
t[x].push_back(o);
if(p == r)
{
sort(t[x].begin() , t[x].end());
int i;
for(i = 0 ; i <= r - l ; i ++ )
{
while(v1[x].size() > 1 && ((t[x][i] - v1[x][v1[x].size() - 1]) ^ (v1[x][v1[x].size() - 2] - v1[x][v1[x].size() - 1])) >= 0) v1[x].pop_back();
v1[x].push_back(t[x][i]);
while(v2[x].size() > 1 && ((t[x][i] - v2[x][v2[x].size() - 1]) ^ (v2[x][v2[x].size() - 2] - v2[x][v2[x].size() - 1])) <= 0) v2[x].pop_back();
v2[x].push_back(t[x][i]);
}
}
if(l == r) return;
int mid = (l + r) >> 1;
if(p <= mid) insert(p , o , lson);
else insert(p , o , rson);
}
ll query1(int b , int e , point o , int l , int r , int x)
{
if(b <= l && r <= e)
{
int L = 1 , R = v1[x].size() - 1 , Mid , Ans = 0;
while(L <= R)
{
Mid = (L + R) >> 1;
if(o * v1[x][Mid] > o * v1[x][Mid - 1]) Ans = Mid , L = Mid + 1;
else R = Mid - 1;
}
return o * v1[x][Ans];
}
int mid = (l + r) >> 1;
ll ans = -1ll << 62;
if(b <= mid) ans = max(ans , query1(b , e , o , lson));
if(e > mid) ans = max(ans , query1(b , e , o , rson));
return ans;
}
ll query2(int b , int e , point o , int l , int r , int x)
{
if(b <= l && r <= e)
{
int L = 1 , R = v2[x].size() - 1 , Mid , Ans = 0;
while(L <= R)
{
Mid = (L + R) >> 1;
if(o * v2[x][Mid] > o * v2[x][Mid - 1]) Ans = Mid , L = Mid + 1;
else R = Mid - 1;
}
return o * v2[x][Ans];
}
int mid = (l + r) >> 1;
ll ans = -1ll << 62;
if(b <= mid) ans = max(ans , query2(b , e , o , lson));
if(e > mid) ans = max(ans , query2(b , e , o , rson));
return ans;
}
int main()
{
int n , tot = 0 , i , l , r;
ll last = 0;
point o;
scanf("%d%s" , &n , opt);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%s%lld%lld" , str , &o.x , &o.y) , o.x ^= last , o.y ^= last;
if(str[0] == 'A') insert(++tot , o , 1 , n , 1);
else
{
scanf("%d%d" , &l , &r) , l ^= last , r ^= last;
if(o.y > 0) last = query1(l , r , o , 1 , n , 1);
else last = query2(l , r , o , 1 , n , 1);
printf("%lld\n" , last) , last &= 0x7fffffff;
if(opt[0] == 'E') last = 0;
}
}
return 0;
}
【bzoj3533】[Sdoi2014]向量集 线段树+STL-vector维护凸包的更多相关文章
- BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)
Description 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); " Q x y l r (| ...
- BZOJ 3533: [Sdoi2014]向量集( 线段树 + 三分 )
答案一定是在凸壳上的(y>0上凸壳, y<0下凸壳). 线段树维护, 至多N次询问, 每次询问影响O(logN)数量级的线段树结点, 每个结点O(logN)暴力建凸壳, 然后O(logN) ...
- bzoj 3533: [Sdoi2014]向量集 线段树维护凸包
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3533 题解: 首先我们把这些向量都平移到原点.这样我们就发现: 对于每次询问所得到的an ...
- bzoj 3533 [Sdoi2014]向量集 线段树+凸包+三分(+动态开数组) 好题
题目大意 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); "Q x y l r (|x|,|y| & ...
- BZOJ3533 [Sdoi2014]向量集 【线段树 + 凸包 + 三分】
题目链接 BZOJ3533 题解 我们设询问的向量为\((x_0,y_0)\),参与乘积的向量为\((x,y)\) 则有 \[ \begin{aligned} ans &= x_0x + y_ ...
- [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]
题面 BZOJ传送门 思路 首先当然是推式子 对于一个询问点$(x_0,y_0$和给定向量$(x_1,y_1)$来说,点积这么表达: $A=x_0x_1+y_0y_1$ 首先肯定是考虑大小关系:$x_ ...
- bzoj3533: [Sdoi2014]向量集
Description 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);" Q x y l r (|x| ...
- 【BZOJ4311】向量(线段树分治,斜率优化)
[BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...
- UVA1455 - Kingdom(并查集 + 线段树)
UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...
随机推荐
- 使用WinIO库实现保护模式下的IO和内存读写
问题已解决: 原因是函数的调用方式与WinIO中不一致,使用的时候漏掉了__stdcall. 函数原定义为: 在实际的GPIO读写中遇到以下问题: SetPortVal可正常写入,但是GetPortV ...
- 4040 EZ系列之奖金 (拓扑)
4040 EZ系列之奖金 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题目描述 Description 由于无敌的WRN在2015年世界英俊帅 ...
- 杂谈001:晨曦Dawn的重新连接
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 摘要: 我是晨曦,好久没有关注过我的博客了,整天都在乱糟糟的忙,叙述一下我消失的这段时间,然后我准备做几个专题 ...
- linux 冒号用法
冒号在Linux中是一个空命令,可以认为与shell的内建命令true相同,它的返回值是0. 在while循环中 while : 与 while true 的作用是等效的 在 if/then 中可作为 ...
- python全栈开发-前方高能-内置函数2
python_day_15 一.今日主要内容 1. lambda 匿名函数 语法: lambda 参数:返回值 不能完成复杂的操作 2. sorted() 函数 排序. 1. 可迭代对象 2. key ...
- LUIS 语义识别API调用方法
本例使用itchat获取微信文字消息,发送给LUIS返回识别消息,再将返回消息格式化后通过微信发回 关于itchat的使用参考我的另外一篇随笔itchat个人练习 语音与文本图灵测试例程 # -*- ...
- git clone、git pull和git fetch的用法及区别
声明:码字不易,转载请注明出处,欢迎文章下方讨论交流.Git 常用命令速查表 最近在一个学习小组里学习AI的课程,我们所有的学习资料和homework都放在gitlab上.今天一个小队友从gitlab ...
- Charles的安装与破解
Charles启动需要安装java环境,不知配置了jdk就可以,而是需要java环境,否则下载后点击启动会提示找不到suitable java 1 安装java环境 安装java环境是在https:/ ...
- ython进阶06 循环对象
这一讲的主要目的是为了大家在读Python程序的时候对循环对象有一个基本概念. 循环对象的并不是随着Python的诞生就存在的,但它的发展迅速,特别是Python 3x的时代,循环对象正在成为循环的标 ...
- 原生WebGL场景中绘制多个圆锥圆柱
前几天解决了原生WebGL开发中的一个问题,就是在一个场景中绘制多个几何网格特征不同的模型,比如本文所做的绘制多个圆锥和圆柱在同一个场景中,今天抽空把解决的办法记录下来,同时也附上代码.首先声明,圆柱 ...