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

题面

BZOJ

题解

先考虑对于给定的向量集,如何求解和当前向量的最大内积。

设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2,v2)\),并且\(u1>u2\)

假设第一个向量的结果优于第二个。

\(xu1+yv1>xu2+yv2\)

移项可以得到

\(x(u1-u2)>y(v2-v1)\)

所以\(x/y>(v2-v1)/(u1-u2)\)

也就是\(-x/y>(v1-v2)/(u1-u2)\)

右边是一个斜率,左边是询问向量和原点构成的斜率的垂线。

所以维护一个上凸壳,每次在上面二分(三分)一下就好了

时间复杂度\(O(nlog^2n)\)

按照之前听到的方法,因为每次询问如果排序之后,二分的结果是单调的,

所以暴力扫一遍就好。时间复杂度\(O(nlogn)\)

我写的是两个log的。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define lson (now<<1)
#define rson (now<<1|1)
#define MAX 200200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Vector{int x,y,l,r;}p[MAX],q[MAX];
bool cmp(Vector a,Vector b)
{
if(a.x!=b.x)return a.x<b.x;
return a.y<b.y;
}
int tot,Tim,n;
ll ans[MAX];
vector<Vector> seg[MAX<<2];
void Modify(int now,int l,int r,int L,int R,int id)
{
if(L<=l&&r<=R){seg[now].push_back(p[id]);return;}
int mid=(l+r)>>1;
if(L<=mid)Modify(lson,l,mid,L,R,id);
if(R>mid)Modify(rson,mid+1,r,L,R,id);
}
ll inner(Vector a,Vector b){return 1ll*a.x*b.x+1ll*a.y*b.y;}
ll Cross(Vector a,Vector b,Vector c){return 1ll*(a.x-c.x)*(b.y-c.y)-1ll*(a.y-c.y)*(b.x-c.x);}
Vector S[MAX];
int Top;
ll Query(int id)
{
int l=1,r=Top;ll ret=0;
while(l+3<=r)
{
int mid1=l+(r-l)/3,mid2=r-(r-l)/3;
if(inner(q[id],S[mid1])<=inner(q[id],S[mid2]))l=mid1;
else r=mid2;
}
for(int i=l;i<=r;++i)ret=max(ret,inner(q[id],S[i]));
return ret;
}
void Work(int now,int l,int r)
{
if(!seg[now].size())return;Top=0;
sort(seg[now].begin(),seg[now].end(),cmp);
for(int i=0,len=seg[now].size();i<len;++i)
{
Vector u=seg[now][i];
while(Top>1&&Cross(S[Top-1],S[Top],u)>=0)--Top;
S[++Top]=seg[now][i];
}
for(int i=l;i<=r;++i)ans[i]=max(ans[i],Query(i));
if(l==r)return;int mid=(l+r)>>1;
}
void Divide(int now,int l,int r)
{
Work(now,l,r);
if(l==r)return;int mid=(l+r)>>1;
Divide(lson,l,mid);Divide(rson,mid+1,r);
}
int main()
{
n=read();
for(int i=1;i<=n;++i)
{
int opt=read();
if(opt==1)
{
int x=read(),y=read();
p[++tot]=(Vector){x,y,Tim+1,-1};
}
else if(opt==2)
p[read()].r=Tim;
else
{
int x=read(),y=read();
q[++Tim]=(Vector){x,y,Tim,Tim};
}
}
for(int i=1;i<=tot;++i)if(p[i].r==-1)p[i].r=Tim;
for(int i=1;i<=tot;++i)if(p[i].l<=p[i].r)Modify(1,1,Tim,p[i].l,p[i].r,i);
Divide(1,1,Tim);
for(int i=1;i<=Tim;++i)printf("%lld\n",ans[i]);
return 0;
}

【BZOJ4311】向量(线段树分治,斜率优化)的更多相关文章

  1. bzoj4311向量(线段树分治+斜率优化)

    第二道线段树分治. 首先设当前向量是(x,y),剩余有两个不同的向量(u1,v1)(u2,v2),假设u1>u2,则移项可得,若(u1,v1)优于(u2,v2),则-x/y>(v1-v2) ...

  2. 【BZOJ3672】【NOI2014】购票(线段树,斜率优化,动态规划)

    [BZOJ3672][NOI2014]购票(线段树,斜率优化,动态规划) 题解 首先考虑\(dp\)的方程,设\(f[i]\)表示\(i\)的最优值 很明显的转移\(f[i]=min(f[j]+(de ...

  3. 【BZOJ-3672】购票 树分治 + 斜率优化DP

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1177  Solved: 562[Submit][Status][ ...

  4. 【BZOJ3672】[Noi2014]购票 树分治+斜率优化

    [BZOJ3672][Noi2014]购票 Description  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.       ...

  5. [BZOJ4311]向量(凸包+三分+线段树分治)

    可以发现答案一定在所有向量终点形成的上凸壳上,于是在上凸壳上三分即可. 对于删除操作,相当于每个向量有一个作用区间,线段树分治即可.$O(n\log^2 n)$ 同时可以发现,当询问按斜率排序后,每个 ...

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

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

  7. BZOJ4311 向量(线段树分治+三分)

    由点积的几何意义(即投影)可以发现答案一定在凸壳上,并且投影的变化是一个单峰函数,可以三分.现在需要处理的只有删除操作,线段树分治即可. #include<iostream> #inclu ...

  8. 洛谷.3733.[HAOI2017]八纵八横(线性基 线段树分治 bitset)

    LOJ 洛谷 最基本的思路同BZOJ2115 Xor,将图中所有环的异或和插入线性基,求一下线性基中数的异或最大值. 用bitset优化一下,暴力的复杂度是\(O(\frac{qmL^2}{w})\) ...

  9. 线段树分治总结(线段树分治,线段树,并查集,树的dfn序,二分图染色)

    闲话 stO猫锟学长,满脑子神仙DS 网上有不少Dalao把线段树分治也归入CDQ分治? 还是听听YCB巨佬的介绍: 狭义:只计算左边对右边的贡献. 广义:只计算外部对内部的贡献. 看来可以理解为广义 ...

随机推荐

  1. Java SE教程

    第0讲 开山篇 读前介绍:本文中如下文本格式是超链接,可以点击跳转 >>超链接<< 我的学习目标:基础要坚如磐石   代码要十份规范   笔记要认真详实 一.java内容介绍 ...

  2. C#课后小作业

    有关C#基础的练手 跟大家一起分享下 1.让用户输入一个100以内的数 打印1-100之间所有的数,用户输入的数除外 2.让用户输入一个100以内的数 打印1-这个数之间所有的数的和 3.使用一个fo ...

  3. git分支在团队中的使用

    须知 在介绍分支常用操作之前 我们需要知道几点: 1.主干不允许做任何修改结构或者业务的操作. 有两种情况可以修改主干: 就是当前主干已经是有问题的,合并后出问题发布不了. 修改与业务无关的配置文件, ...

  4. 2018百度之星开发者大赛-paddlepaddle学习

    前言 本次比赛赛题是进行人流密度的估计,因为之前看过很多人体姿态估计和目标检测的论文,隐约感觉到可以用到这次比赛上来,所以趁着现在时间比较多,赶紧报名参加了一下比赛,比赛规定用paddlepaddle ...

  5. Maven私库

    <server> <id>releases</id> <username>admin</username> <password> ...

  6. [MYSQL]练习(一)

    本文转载自:http://www.cnblogs.com/DreamDrive/p/6193530.html 我只是想做一个自己的运维知识库,所以迫不得已做了搬运工 建表 DROP TABLE DEP ...

  7. RyuBook1.0案例三:REST Linkage

    REST Linkage 该小结主要介绍如何添加一个REST Link 函数 RYU本身提供了一个类似WSGI的web服务器功能.借助这个功能,我们可以创建一个REST API. 基于创建的REST ...

  8. org.apache.poi版本问题

    问题描述: 今天跑一段历史代码,发现不能启动,抛出java.lang.NoSuchFieldError: RETURN_NULL_AND_BLANK 问题 解决办法: 把org.apache.poi的 ...

  9. VMware VSAN 入门与配置(一)

    ----VMware VSAN beta版已经出来一段时间了,今天终于正式发布(同时VMware View 5.3.1也正是发布,在5.3的基础上增加了VSAN的支持) VSAN 产品主页 http: ...

  10. oozie的shell-action中加入hive脚本命令启动执行shell同时操作hive,抛异常Container killed on request. Exit code is 143 Container exited with a non-zero exit code 143

    使用oozie来调度操作,用shell的action执行命令,其中shell里包含着hive -e 操作执行时,oozie窗口报 WARN ShellActionExecutor: - SERVER[ ...