题意:要求支持三个操作,加入删除一个向量,询问当前向量与给定向量的最大值。

题解:线段树时间分治,每个区间做一个凸包,查询的时候到对应区间的凸包上三分。

(话说我这个可能有点问题,三分那一块R-L>=20我才过的。。)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define LL long long
  4. #define N 300005
  5.  
  6. inline LL read(){
  7. LL x=,f=; char a=getchar();
  8. while(a<'' || a>'') {if(a=='-') f=-; a=getchar();}
  9. while(a>='' && a<='') x=x*+a-'',a=getchar();
  10. return x*f;
  11. }
  12.  
  13. int n,cnt,st[N],ed[N],qnum,root,ti[N];
  14. LL ans;
  15.  
  16. struct point{
  17. LL x,y;
  18. bool operator < (const point& w)const{
  19. if(x==w.x) return y<w.y;
  20. return x<w.x;
  21. }
  22. }p[N],Q[N],tmp[N];
  23.  
  24. point operator - (const point& a,const point& b){return (point){a.x-b.x,a.y-b.y};}
  25.  
  26. inline LL cross(point a,point b){return a.x*b.y-a.y*b.x;}
  27.  
  28. LL operator * (const point& a,const point& b){
  29. return a.x*b.x+a.y*b.y;
  30. }
  31.  
  32. struct segment{
  33. int l,r;
  34. vector<point>s;
  35. }a[*N];
  36.  
  37. void build(int k,int l,int r){
  38. a[k].l=l; a[k].r=r;
  39. if(l==r) return;
  40. int mid=(l+r)>>;
  41. build(k<<,l,mid); build(k<<|,mid+,r);
  42. }
  43.  
  44. void insert(int k,int L,int R,int x){
  45. int l=a[k].l,r=a[k].r;
  46. if(l==L && r==R) {a[k].s.push_back(p[x]); return;}
  47. int mid=(l+r)>>;
  48. if(R<=mid) insert(k<<,L,R,x);
  49. else if(mid<L) insert(k<<|,L,R,x);
  50. else insert(k<<,L,mid,x),insert(k<<|,mid+,R,x);
  51. }
  52.  
  53. void convexhull(int k){
  54. if(!a[k].l) return;
  55. int len=a[k].s.size();
  56. sort(a[k].s.begin(),a[k].s.end());
  57. int top=;
  58. for(int i=;i<len;i++){
  59. while(top> && cross(a[k].s[i]-tmp[top-],tmp[top]-tmp[top-])>=) top--;
  60. tmp[++top]=a[k].s[i];
  61. }
  62. int tt=top;
  63. for(int i=len-;i>=;i--){
  64. while(top>tt && cross(a[k].s[i]-tmp[top-],tmp[top]-tmp[top-])>=) top--;
  65. tmp[++top]=a[k].s[i];
  66. }
  67. if(len>) top--;
  68. a[k].s.clear();
  69. for(int i=;i<=top;i++) a[k].s.push_back(tmp[i]);
  70. convexhull(k<<); convexhull(k<<|);
  71. }
  72.  
  73. void query(int k,int pos,int num){
  74. int l=a[k].l,r=a[k].r;
  75. int L=,R=a[k].s.size()-;
  76. while(R-L>=){
  77. int ll=L+(R-L)/,rr=R-(R-L)/;
  78. if(Q[num]*a[k].s[ll]>Q[num]*a[k].s[rr]) R=rr;
  79. else L=ll;
  80. }
  81. for(int i=L;i<=R;i++)
  82. ans=max(ans,Q[num]*a[k].s[i]);
  83. if(l==r) return;
  84. int mid=(l+r)>>;
  85. if(pos<=mid) query(k<<,pos,num);
  86. else query(k<<|,pos,num);
  87. }
  88.  
  89. int main(){
  90. n=read();
  91. for(int i=;i<=n;i++){
  92. int type=read();
  93. if(type==) p[++cnt].x=read(),p[cnt].y=read(),st[cnt]=i;
  94. else if(type==) ed[read()]=i;
  95. else Q[++qnum].x=read(),Q[qnum].y=read(),ti[qnum]=i;
  96. }
  97. build(,,n);
  98. for(int i=;i<=cnt;i++) if(!ed[i]) ed[i]=n;
  99. for(int i=;i<=cnt;i++) insert(,st[i],ed[i],i);
  100. convexhull();
  101. for(int i=;i<=qnum;i++) ans=,query(,ti[i],i),printf("%lld\n",ans);
  102. return ;
  103. }

BZOJ4311:向量的更多相关文章

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

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

  2. BZOJ4311 : 向量

    考虑离线操作,求出每个向量存在的时间区间,用时间线段树来进行分治,在每个节点求出凸壳后,询问时在凸壳上三分答案.时间复杂度$O(n\log^2n)$. #include<cstdio> # ...

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

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

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

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

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

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

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

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

  7. 【bzoj4311】向量 线段树对时间分治+STL-vector维护凸包

    题目描述 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y)点积的最大值是多少.如果当前是空集输出0 输入 第一行输入一个整数n, ...

  8. BZOJ4311:向量——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4311 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 ...

  9. 机器学习实战笔记(Python实现)-05-支持向量机(SVM)

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

随机推荐

  1. Linux(Centos6.5)下安装svn服务器,并通过http访问

    linux安装svn其实很容易,个人觉得难就难在配置上,反复配置,琢磨,查找相关资料,总算是成功了.. 安装: 安装svn,一般情况下,选择yum方式安装还是比较简单的. ? 1 2 [root@mo ...

  2. openssl 升级操作 -2

    首先我觉得没事就用绿盟扫漏洞的公司,就是闲的蛋疼,傻逼!不少服务器使用nginx,如果openssl 是静态编译的,直接将openssl 编译到nginx里面去了,这就意味着,单纯升级openssl ...

  3. 在执行save操作时候出现的诡异!

    情景:有一份excel数据需要导入到数据库中,想了想就写了一个导入excel的小功能. .............................准备使用时候,就开搞了,擦! 什么鬼??? 全程无报错 ...

  4. centos系统时间相差8个小时解决方案

    查看当前系统时间 [root@centos64 ~]# date 查看硬件时间 [root@centos64 ~]# hwclock --show 同步时间可以用:ntpdate us.pool.nt ...

  5. Map.Entry<K,V>分析

    一.好处 你是否已经对每次从Map中取得关键字然后再取得相应的值感觉厌倦? Set keys = map.keySet( ); if(keys != null) { Iterator iterator ...

  6. MD5,SHA256,时间戳获取

    import hashlib # MD5加密 def jiamimd5(src): m = hashlib.md5() m.update(src.encode('UTF-8')) return m.h ...

  7. 2、Python request、BeautifulSoup(download mm_pic)

    import requests from bs4 import BeautifulSoup import os class DownLoadImg(object): def __init__(self ...

  8. centos中screen的使用 创建 退出

    一.创建一个新窗口: 安装完成后,直接敲命令screen就可以启动它.但是这样启动的screen会话没有名字,实践上推荐为每个screen会话取一个名字,方便分辨: [root@elk-server ...

  9. MySQL学习思维导图

    结束:分享在线下载地址 https://www.xmind.net/m/7t6U/

  10. php 计算器的例子

    php实现的计算器的例子,代码如下: <html>     <head>         <title>PHP实现简单计算器-www.jbxue.com</t ...