正题

题目链接:https://www.luogu.com.cn/problem/P3309


题目大意

nnn个操作

  1. 在序列末尾加入一个向量(x,y)(x,y)(x,y)
  2. 询问加入的第l∼rl\sim rl∼r个向量中的一个向量和(x,y)(x,y)(x,y)的点积最大值

强制在线,点积的定义为x1x2+y1y2x_1x_2+y_1y_2x1​x2​+y1​y2​


解题思路

如果对于一个(x,y)(x,y)(x,y)对于两个(x1,y1)(x_1,y_1)(x1​,y1​)和(x2,y2)(x_2,y_2)(x2​,y2​)如果后者更大那么有
x2x+y2y>x1x+y1y⇒yx≤x2−x1y2−y1x_2x+y_2y>x_1x+y_1y\Rightarrow \frac{y}{x}\leq \frac{x_2-x_1}{y_2-y_1}x2​x+y2​y>x1​x+y1​y⇒xy​≤y2​−y1​x2​−x1​​
好像和斜率有关,可以维护凸壳来做,因为yyy可能是负数,如果是负数的时候就要求的是下凸壳了,所以两个凸壳都要维护。

因为强制在线所以上不了传统艺能CDQ\text{CDQ}CDQ

那怎么动态维护区间凸壳,平衡树支持动态插入但不支持区间问题。所以考虑线段树,因为一个位置修改了之后就不会再修改,而且是从左往右加的,可以利用这个性质。

每次我们修改一个位置后,如果一个区间[L,R][L,R][L,R]的节点内已经插入了R−L+1R-L+1R−L+1个向量(也就是都插完了)的话就直接把它的两个儿子的凸壳合并起来。

然后询问的时候分成lognlog\ nlog n个区间询问的答案取最大值就好了。

合并凸壳的是用归并排序的话时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
struct point{ll x,y;point(ll xx=0,ll yy=0){x=xx;y=yy;return;}
}z;
point operator+(point x,point y)
{return point(x.x+y.x,x.y+y.y);}
point operator-(point x,point y)
{return point(x.x-y.x,x.y-y.y);}
ll operator^(point x,point y)
{return x.x*y.y-x.y*y.x;}
ll operator*(point x,point y)
{return x.x*y.x+x.y*y.y;}
bool operator<(point x,point y)
{return (x.x==y.x)?x.y<y.y:x.x<y.x;}const ll N=4e5+10;
char pe[3];
ll n,num,siz[N<<2];
vector<point> v[N<<2][2],tmp;void Make(ll x){ll ls=x*2,rs=x*2+1;for(ll k=0;k<2;k++){ll i=0,j=0,l1=v[ls][k].size()-1,l2=v[rs][k].size()-1;tmp.clear();while(i<=l1||j<=l2){if(i>l1||(j<=l2&&v[rs][k][j]<v[ls][k][i]))tmp.push_back(v[rs][k][j]),j++;else tmp.push_back(v[ls][k][i]),i++;}ll cnt=0;for(ll i=0;i<tmp.size();i++){while(cnt>1&&((v[x][k][cnt-1]-v[x][k][cnt-2])^(tmp[i]-v[x][k][cnt-1]))>=0)v[x][k].pop_back(),cnt--;v[x][k].push_back(tmp[i]);cnt++;}}return;
}
ll Calc(ll x,point p){ll f=0;if(p.y<0)p=z-p,f^=1;ll l=0,r=v[x][f].size()-2;while(l<=r){ll mid=(l+r)>>1;point tmp=v[x][f][mid+1]-v[x][f][mid];tmp.x*=-1;if(p.x*tmp.x>=p.y*tmp.y)r=mid-1;else l=mid+1;}return p*v[x][f][l];
}
void Change(ll x,ll L,ll R,ll pos,point p){if(L==R){v[x][0].push_back(p);v[x][1].push_back(z-p);return;}ll mid=(L+R)>>1;siz[x]++;if(pos<=mid)Change(x*2,L,mid,pos,p);else Change(x*2+1,mid+1,R,pos,p);if(siz[x]==R-L+1)Make(x);
}
ll Ask(ll x,ll L,ll R,ll l,ll r,point p){if(L==l&&R==r)return Calc(x,p);ll mid=(L+R)>>1;if(r<=mid)return Ask(x*2,L,mid,l,r,p);if(l>mid)return Ask(x*2+1,mid+1,R,l,r,p);return max(Ask(x*2,L,mid,l,mid,p),Ask(x*2+1,mid+1,R,mid+1,r,p));
}
void dc(ll &x,ll lastans) {if(pe[0]=='E')return;x=x^(lastans&0x7fffffff);return;
}
signed main()
{scanf("%lld%s",&n,pe);ll last=0;for(ll i=1;i<=n;i++){char op[3];ll x,y,l,r;scanf("%s%lld%lld",op,&x,&y);dc(x,last);dc(y,last);if(op[0]=='A'){++num;Change(1,1,n,num,point(x,y));}else{scanf("%lld%lld",&l,&r);dc(l,last);dc(r,last);printf("%lld\n",last=Ask(1,1,n,l,r,point(x,y)));}}return 0;
}

P3309-[SDOI2014]向量集【线段树,凸壳】相关推荐

  1. 暑期集训5:并查集 线段树 练习题G: HDU - 1754

    2018学校暑期集训第五天--并查集 线段树 练习题G  --   HDU - 1754 I Hate It 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.  这让 ...

  2. 暑期集训5:并查集 线段树 练习题F:  HDU - 1166 ​​​​​​​

    2018学校暑期集训第五天--并查集 线段树 练习题F  --   HDU - 1166 敌兵布阵 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A ...

  3. 暑期集训5:并查集 线段树 练习题B: HDU - 1213 ​​​​​​​

    2018学校暑期集训第五天--并查集 线段树 练习题B  --   HDU - 1213 How Many Tables Today is Ignatius' birthday. He invites ...

  4. 暑期集训5:并查集 线段树 练习题A:  HDU - 1232 ​​​​​​​

    2018学校暑期集训第五天--并查集 线段树 练习题A  --   HDU - 1232 畅通工程 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅 ...

  5. UVA1455 - Kingdom(并查集 + 线段树)

    UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...

  6. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  7. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  8. bzoj3533 [Sdoi2014]向量集 可持久化凸包+二分

    首先,x和y都小于一个向量且都大于一个向量的点一定是没有用的 这样就相当于挖掉了决策中位置偏中间的点,然后要求ax+by的最小值 设 ax+by=k,则 y=k/b-a/bx  ,就变成了类似斜率优化 ...

  9. 线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

    题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边 ...

最新文章

  1. 【Network Security!】Ubuntu18.04切换到root权限和sudo
  2. spring+mybatis 多数据源整合
  3. (转) 设置sqlplus中的退格键
  4. 用memcached实现session共享
  5. maven项目发布到tomcat里lib包没有发布的问题
  6. python开发项目架构图_我的第一个python web开发框架(8)——项目结构与RESTful接口风格说明...
  7. 数字图像处理--彩色图像转灰度图像
  8. centos mysql-5.5.20_mysql-5.5.20+CentOS 6.2 编译安装全过程详解(2)
  9. 【数学建模】day05-微分方程建模
  10. 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) ...ubuntu 18.04 安装vim遇到的错误...
  11. Spring实例化bean的三种方法
  12. Proteus软件的安装与使用方法(超详细)
  13. Using openRefine
  14. Pycharm 用鼠标滚轮控制字体大小
  15. 对Volterra级数公式的理解-1
  16. 红米note3android驱动,红米Note3手机驱动
  17. 网络工程师有什么发展?
  18. 如何修复excel文件损坏
  19. turtle画奥运五环图
  20. Java内部类的四种分类以及作用

热门文章

  1. c语言md5函数 linux,Linux下C语言计算文件的md5值(长度32)
  2. 图像处理前沿技术_深入浅出人工智能前沿技术—机器视觉检测,看清人类智慧工业...
  3. .Net性能调优-垃圾回收!!!最全垃圾回收来了
  4. 在linux中查找运行程序句柄,如何查找我的进程在Linux中打开的文件句柄?
  5. 川大计算机文化基础在线作业,川大1309《计算机文化基础0008》在线作业2答案.docx...
  6. linux accept过程,Linux协议栈accept和syn队列问题
  7. 2020项目商机_2020未来商机,一万元可以做什么项目
  8. java8 垃圾 不同_【不同的Java垃圾回收器的比较】
  9. categories php,manage-categories.php
  10. 数据结构——图-有向带权图的邻接表基础