传送门

达成成就:一人独霸三页提交

自己写的莫名其妙MLE死都不知道怎么回事,照着题解打一直RE一个点最后发现竟然是凸包上一个点求错了……四个半小时就一直用来调代码了……

那么我们只要维护好这个凸壳,因为这是一个凸函数,所以只要在上面三分找最值即可

于是现在我们需要维护一个资瓷插入的凸壳。考虑线段树,我们发现每一次在线段树上询问的区间必然都是已经把点插满了的。那么我们可以考虑线段树上每一个节点内的所有元素都插入完之后,再构建凸壳,那么显然每个节点只会被构建一次凸包,所以复杂度是\(O(nlog^2n)\)

然后注意一个细节……因为我们维护好的凸包要便于分成上下凸壳,所以凸包的起点应该是\(x\)坐标最小的,这样才满足它左右两边分别是上凸壳和下凸壳……我按照以前的写法找\(y\)坐标最小的当起点然后就没有然后了……

//minamoto
#include<bits/stdc++.h>
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
#define ll long long
#define inf 1e18
using namespace std;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
int flag=0,all;ll lasans=0;
int read(){
int res,f=1;char ch;
while((ch=getchar())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getchar())>='0'&&ch<='9';res=res*10+ch-'0');
res*=f;if(flag)res^=(lasans&0x7fffffff);
return res;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(ll x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=4e5+5;
struct node{int x,y;}b[N],st[N];
struct seg{
int l,r,pos,sz;seg *ch[2];
vector<node>mp;
}pool[N<<2],*rt;
inline node operator -(node a,node b){return (node){a.x-b.x,a.y-b.y};}
inline ll operator *(node a,node b){return 1ll*a.x*b.y-1ll*b.x*a.y;}
inline ll dot(node a,node b){return 1ll*a.x*b.x+1ll*a.y*b.y;}
inline bool operator <(node a,node b){
a=a-st[1],b=b-st[1];
return a*b==0?1ll*a.x*a.x+1ll*a.y*a.y<1ll*b.x*b.x+1ll*b.y*b.y:a*b>0;
}
void graham(seg *p){
int top=1,sz=p->r-p->l+1,k=1;
fp(i,1,sz)b[i]=p->mp[i-1];
fp(i,2,sz)if(b[i].x<b[k].x||(b[i].x==b[k].x&&b[i].y<b[k].y))k=i;
swap(b[1],b[k]),st[1]=b[1],sort(b+2,b+sz+1);
fp(i,2,sz){
while(top>1&&(b[i]-st[top-1])*(st[top]-st[top-1])>=0)--top;
st[++top]=b[i];
}st[++top]=b[1];p->sz=top;
vector<node>().swap(p->mp);
// p->mp.clear();
fp(i,1,top)p->mp.push_back(st[i]);
fp(i,1,top-1)if(st[i+1].x<=st[i].x){p->pos=i-1;break;}
}
ll calc(seg *p,node q){
int l,r,m1,m2;ll ans=-inf;
q.y>0?(l=p->pos,r=p->sz-1):(l=0,r=p->pos);
while(r-l>=3){
m1=l+(r-l)/3,m2=r-(r-l)/3;
dot(q,p->mp[m1])>dot(q,p->mp[m2])?r=m2:l=m1;
}fp(i,l,r)cmax(ans,dot(q,p->mp[i]));return ans;
}
void ins(seg *p,int pos,node x){
p->mp.push_back(x);if(pos==p->r)graham(p);if(p->l==p->r)return;
int mid=(p->l+p->r)>>1;pos<=mid?ins(p->ch[0],pos,x):ins(p->ch[1],pos,x);
}
ll query(seg *p,int l,int r,node x){
if(l<=p->l&&r>=p->r)return calc(p,x);
int mid=(p->l+p->r)>>1;ll res=-inf;
if(l<=mid)cmax(res,query(p->ch[0],l,r,x));
if(r>mid)cmax(res,query(p->ch[1],l,r,x));
return res;
}
void build(seg *p,int l,int r){
p->l=l,p->r=r;if(l==r)return;int mid=(l+r)>>1;
build(p->ch[0]=pool+ ++all,l,mid),build(p->ch[1]=pool+ ++all,mid+1,r);
}
int main(){
// freopen("testdata.in","r",stdin);
int n,l,r,tot=0;char s[10];node x;
n=read(),scanf("%s",s),flag=s[0]!='E';
build(rt=pool+ ++all,1,n);
while(n--){
scanf("%s",s),x.x=read(),x.y=read();
if(s[0]=='Q')l=read(),r=read(),print(lasans=query(rt,l,r,x));
else ins(rt,++tot,x);
}return Ot(),0;
}

P3309 [SDOI2014]向量集的更多相关文章

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

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

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

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

  3. bzoj3533: [Sdoi2014]向量集

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

  4. BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)

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

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

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

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

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

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

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

  8. Sdoi2014 向量集

    题目描述 题解: 码力太差重构之后才$A……$ 首先求向量点积最大很容易想到凸包, 设已知$(x_0,y_0)$,求$(x,y)$满足$(x,y)*(x_0,y_0)>=(x',y')*(x_0 ...

  9. SDOI 2014 向量集

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

随机推荐

  1. 「 Luogu P2230 」X 「 Vijos 1142 」 HXOS系统

    题目描述可能稍有偏差,但实质上是一样的. 看下面 题目大意 题面这么长,先说说题意吧. 就是有一个操作系统,他的存储方式是树形的.其中分为文件和目录(文件夹)每一个子目录下只能存储 $K$ 个文件或目 ...

  2. Luogu P3802 小魔女帕琪

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  3. java解析从接口获取的json内容并写到excle(只写与标题匹配的值,并非把所有的接口返回值都写进去)

    需求:从接口中获取的一个json数组中有多个对象,每个对象中的值并非都需要,只需查出标题中的几项对应的值即可.且还需要按某个字段排序后依次写到excel 实现方法如下: package jansonD ...

  4. vuex----------state的基础用法

    先使用vue cli构建一个自己的vue项目 1.npm i -g vue-cli 2.vue init webpack sell (sell是你的项目名) 3.一路回车(在这个过程中会提示你是否安装 ...

  5. Hdu 5806 NanoApe Loves Sequence Ⅱ(双指针) (C++,Java)

    Hdu 5806 NanoApe Loves Sequence Ⅱ(双指针) Hdu 5806 题意:给出一个数组,求区间第k大的数大于等于m的区间个数 #include<queue> # ...

  6. pat甲级 1107. Social Clusters (30)

    When register on a social network, you are always asked to specify your hobbies in order to find som ...

  7. Codeforces Round #240 (Div. 2) D

    , b2, ..., bl (1 ≤ b1 ≤ b2 ≤ ... ≤ bl ≤ n) is called good if each number divides (without a remainde ...

  8. [bzoj1176]Mokia[CDQ分治]

    啃了一天论文,发现CDQ分治的原理其实很简单,大概就是这样的一类分治:将左右区间按一定规律排序后分开处理,递归到底时直接计算答案,对于一个区间,按照第二关键字split成两个区间,先处理左区间,之后因 ...

  9. project处理 InteropServices.COMException 异常

    project文件无法上传,在上传中的hangfire出现了这个异常 System.Runtime.InteropServices.COMException 这个是因为website的权限是IUser ...

  10. 洛谷 P2683 小岛

    P2683 小岛 题目背景 西伯利亚北部的寒地,坐落着由 N 个小岛组成的岛屿群,我们把这些小岛依次编号为 1 到 N . 题目描述 起初,岛屿之间没有任何的航线.后来随着交通的发展,逐渐出现了一些连 ...