Description

维护一个向量集合,在线支持以下操作:
"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)的点积的最大值。
集合初始时为空。

Input

输入的第一行包含整数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。

Output

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

Sample Input

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

Sample Output

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

HINT

1 < =N < =4×10^5

Solution

设查询的点为$(a,b)$,那么我们需要在当前平面上找一个点$(x,y)$,使得$ax+by=c$的$c$最大化。

把式子化一下为$y=-\frac{a}{b}x+\frac{c}{b}$。

也就是斜率固定,我们要最大化$c$。比较显然的是这条直线肯定是在凸包上取到答案,现在的问题是怎么维护这个凸包。

可以发现因为我们只需要点积的最大值,并不需要凸包的具体形态,所以我们可以开一颗线段树,每个节点维护对应区间的凸包,查询时把区间对应到线段树上的$log$个区间然后取$max$就好了。

现在的问题是怎么修改。如果每次修改都重构线段树节点上的凸包的话,一次修改是$nlogn$的。

不过我们发现可以不用一次修改所有的节点,线段树上的一个区间,会被用到当且仅当这个区间内的点已经全被插入了。这样一次修改的复杂度就是均摊$logn$的了,复杂度证明还是比较显然的……

当$b>0$时,截距越大,$c$越大,我们在上凸壳上三分。

当$b<0$时,截距越小,$c$越大,我们在下凸壳上三分。

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#define N (400009)
#define LL long long
using namespace std; struct Vector
{
LL x,y;
Vector(double xx=,double yy=)
{
x=xx; y=yy;
}
bool operator < (const Vector &a) const
{
return x==a.x?y<a.y:x<a.x;
}
}a[N],P[N];
typedef Vector Point; int n,x,y,l,r,cnt;
LL ans;
char s[],opt[];
vector<Point>U[N<<],D[N<<]; Vector operator - (Vector a,Vector b) {return Vector(a.x-b.x,a.y-b.y);}
LL Cross(Vector a,Vector b) {return a.x*b.y-a.y*b.x;}
LL Dot(Vector a,Vector b) {return a.x*b.x+a.y*b.y;} void decode(int &x)
{
x=x^(ans&0x7fffffff);
} void ConvexHull(int now,int l,int r)
{
for (int i=l; i<=r; ++i) a[i]=P[i];
sort(a+l,a+r+);
int h=;
for (int i=l; i<=r; ++i)
{
while (h> && Cross(a[i]-U[now][h-],U[now][h-]-U[now][h-])<=)
h--, U[now].pop_back();
h++; U[now].push_back(a[i]);
}
h=;
for (int i=l; i<=r; ++i)
{
while (h> && Cross(a[i]-D[now][h-],D[now][h-]-D[now][h-])>=)
h--, D[now].pop_back();
h++; D[now].push_back(a[i]);
}
} void Update(int now,int l,int r,int x)
{
if (l==r)
{
U[now].push_back(P[x]);
D[now].push_back(P[x]);
return;
}
int mid=(l+r)>>;
if (x<=mid) Update(now<<,l,mid,x);
else Update(now<<|,mid+,r,x);
if (x==r) ConvexHull(now,l,r);
} LL Query(int now,int l,int r,int l1,int r1)
{
if (l>r1 || r<l1) return -1e18;
if (l1<=l && r<=r1)
{
if (y>)
{
int L=,R=U[now].size()-;
Point p=Point(x,y);
if (L==R) return Dot(p,U[now][L]);
else if (L+==R) return max(Dot(p,U[now][L]),Dot(p,U[now][R]));
while (R-L>=)
{
int lmid=L+(R-L+)/,rmid=L+(R-L+)/*;
LL ans1=Dot(p,U[now][lmid]);
LL ans2=Dot(p,U[now][rmid]);
if (ans1>ans2) R=rmid;
else L=lmid;
}
return max(Dot(p,U[now][L]),max(Dot(p,U[now][R]),Dot(p,U[now][R-])));
}
else
{
int L=,R=D[now].size()-;
Point p=Point(x,y);
while (R-L>=)
{
int lmid=L+(R-L+)/,rmid=L+(R-L+)/*;
LL ans1=Dot(p,D[now][lmid]);
LL ans2=Dot(p,D[now][rmid]);
if (ans1>ans2) R=rmid;
else L=lmid;
}
return max(Dot(p,D[now][L]),max(Dot(p,D[now][R]),Dot(p,D[now][R-])));
}
}
int mid=(l+r)>>;
return max(Query(now<<,l,mid,l1,r1),Query(now<<|,mid+,r,l1,r1));
} int main()
{
scanf("%d%s",&n,s);
for (int i=; i<=n; ++i)
{
scanf("%s",opt);
if (opt[]=='A')
{
scanf("%d%d",&x,&y);
if (s[]!='E') decode(x), decode(y);
P[++cnt]=Point(x,y);
Update(,,n,cnt);
}
else
{
scanf("%d%d%d%d",&x,&y,&l,&r);
if (s[]!='E') decode(x), decode(y), decode(l), decode(r);
ans=Query(,,n,l,r);
printf("%lld\n",ans);
}
}
}

BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)的更多相关文章

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

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

  2. bzoj 3533: [Sdoi2014]向量集 线段树维护凸包

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3533 题解: 首先我们把这些向量都平移到原点.这样我们就发现: 对于每次询问所得到的an ...

  3. bzoj 3533 [Sdoi2014]向量集 线段树+凸包+三分(+动态开数组) 好题

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

  4. 【bzoj3533】[Sdoi2014]向量集 线段树+STL-vector维护凸包

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

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

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

  6. [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]

    题面 BZOJ传送门 思路 首先当然是推式子 对于一个询问点$(x_0,y_0$和给定向量$(x_1,y_1)$来说,点积这么表达: $A=x_0x_1+y_0y_1$ 首先肯定是考虑大小关系:$x_ ...

  7. bzoj3533: [Sdoi2014]向量集

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

  8. 2019.02.26 bzoj4311: 向量(线段树分治+凸包)

    传送门 题意: 支持插入一个向量,删去某一个现有的向量,查询现有的所有向量与给出的一个向量的点积的最大值. 思路: 考虑线段树分治. 先对于每个向量处理出其有效时间放到线段树上面,然后考虑查询:对于两 ...

  9. 【BZOJ4311】向量(线段树分治,斜率优化)

    [BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...

随机推荐

  1. echart 数据视图 样式重写

    来源http://blog.csdn.net/u010705091/article/details/75212724 echarts折线图的数据视图样式重写 在echarts.js中,点击折线图的数据 ...

  2. 【MongoDB学习-安装流程】

    MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型. ...

  3. Redis哨兵(sentinel)模式搭建

    一.Sentinel介绍 之前骚了一波Redis的简介及应用场景,今天试了下他的哨兵模式: Sentinel是Redis的高可用性(HA)解决方案,由一个或多个Sentinel实例组成的Sentine ...

  4. 深入理解 Java Object

    Java中的Object对象为所有对象的直接或间接父对象,里面定义的几个方法容易被忽略却非常重要.以下来自Effective Java 对Object中几个关键方法的应用说明. public clas ...

  5. ElasticSearch 使用小结

    写在前面 要做个元数据服务,包括存储和查询.元数据除了一些基本字段外,其他格式是自由的,存储输入为一个JSON形式.比如下面是一个文件对象的元数据: { "name":" ...

  6. 背景平铺(兼容IE8)

    标准浏览器通过background-size属性设置;IE8以下通过滤镜实现. 代码如下: /* IE8 */ filter: progid:DXImageTransform.Microsoft.Al ...

  7. 解决stackoverflow打开缓慢的问题

    一.原因: 因为stackoverflow用的是谷歌的api,在国内谷歌是被禁用的,所以才会打开缓慢,并不是stackverflow被墙 二.解决方法: 1.如果你正在使用的是火狐浏览器,那么请按照下 ...

  8. Flutter 图片如何充满父布局

    正常我们需要显示一张图片,会用到Image这个控件.打个比方,我们加载一张本地的图片,先看一下这个Image.asset的源码: Image.asset(String name, { Key key, ...

  9. android 性能优化 -- 启动过程 冷启动 热启动

    一.应用的启动方式 通常来说,启动方式分为两种:冷启动和热启动. 1.冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动. 2.热启动:当启 ...

  10. Expo大作战(十四)--expo中消息推送的实现

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...