P3309-[SDOI2014]向量集【线段树,凸壳】
正题
题目链接:https://www.luogu.com.cn/problem/P3309
题目大意
\(n\)个操作
- 在序列末尾加入一个向量\((x,y)\)
- 询问加入的第\(l\sim r\)个向量中的一个向量和\((x,y)\)的点积最大值
强制在线,点积的定义为\(x_1x_2+y_1y_2\)
解题思路
如果对于一个\((x,y)\)对于两个\((x_1,y_1)\)和\((x_2,y_2)\)如果后者更大那么有
\]
好像和斜率有关,可以维护凸壳来做,因为\(y\)可能是负数,如果是负数的时候就要求的是下凸壳了,所以两个凸壳都要维护。
因为强制在线所以上不了传统艺能\(\text{CDQ}\)
那怎么动态维护区间凸壳,平衡树支持动态插入但不支持区间问题。所以考虑线段树,因为一个位置修改了之后就不会再修改,而且是从左往右加的,可以利用这个性质。
每次我们修改一个位置后,如果一个区间\([L,R]\)的节点内已经插入了\(R-L+1\)个向量(也就是都插完了)的话就直接把它的两个儿子的凸壳合并起来。
然后询问的时候分成\(log\ n\)个区间询问的答案取最大值就好了。
合并凸壳的是用归并排序的话时间复杂度\(O(n\log n)\)
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]向量集【线段树,凸壳】的更多相关文章
- BZOJ 3533: [Sdoi2014]向量集( 线段树 + 三分 )
答案一定是在凸壳上的(y>0上凸壳, y<0下凸壳). 线段树维护, 至多N次询问, 每次询问影响O(logN)数量级的线段树结点, 每个结点O(logN)暴力建凸壳, 然后O(logN) ...
- BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)
Description 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); " Q x y l r (| ...
- 【bzoj3533】[Sdoi2014]向量集 线段树+STL-vector维护凸包
题目描述 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);"Q x y l r (|x|,|y| < ...
- 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| & ...
- [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]
题面 BZOJ传送门 思路 首先当然是推式子 对于一个询问点$(x_0,y_0$和给定向量$(x_1,y_1)$来说,点积这么表达: $A=x_0x_1+y_0y_1$ 首先肯定是考虑大小关系:$x_ ...
- P3309 [SDOI2014]向量集
传送门 达成成就:一人独霸三页提交 自己写的莫名其妙MLE死都不知道怎么回事,照着题解打一直RE一个点最后发现竟然是凸包上一个点求错了--四个半小时就一直用来调代码了-- 那么我们只要维护好这个凸壳, ...
- 【BZOJ4311】向量(线段树分治,斜率优化)
[BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...
- UVA1455 - Kingdom(并查集 + 线段树)
UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...
随机推荐
- 05.SpringMVC之请求映射
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或者方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. @RequestMapping注解有六个属性,下面进 ...
- await 关键字 后面跟Task 和Task <T>
1.Task的优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便.比如: ◆ ThreadPool不支持线程的取消.完成.失败通知等交互性 ...
- Git pull and push
转自:https://blog.csdn.net/qq_41306423/article/details/101701991 关于 git pull 和 git pull origin develop ...
- Spring第一课:核心API(三)
以上是Spring的核心部分,其中需要了解的是:BeanFactory.ApplicationContext[FileSystemXmlApplicationContext.ClassPathXmlA ...
- playwright-python 处理Text input、Checkboxs 和 radio buttons(三)
Text input 输入框输入元素,直接用fill方法即可,支持 <input>,<textarea>, [contenteditable] 和<label>这些 ...
- 微信小程序 转盘抽奖 倒计时 整点
xml: <view id="luckdraw_box"> <view id="luckdraw_back"> <image st ...
- Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用
原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...
- Linux下Sed命令替换文件中的所有IP
命令: sed -ri 's/([0-9]{1,3}\.){3}[0-9]{1,3}/localhost/g' es_create_index.sh 如图:
- SAR总结
1.星载InSAR技术简介 星载合成孔径雷达干涉测量(InSAR)是一种用于大地测量和遥感的雷达技术.InSAR使用两个或多个SAR图像,利用返回卫星的波的相位差来计算目标地区的地形.地貌以及表面的微 ...
- 20210816 你相信引力吗,marshland,party?,半夜
考场 第一眼都不可做 T1 长得就像单调栈/单调队列,推了推性质发现优弧.劣弧都合法的点对很好处理,其他情况只在一种情况合法,那么开两个单调队列分别统计距离 \(\le\frac2n,>\fra ...