bzoj3533: [Sdoi2014]向量集

时间:2022-09-03 10:06:04

Description

维护一个向量集合,在线支持以下操作:
"A x y (|x|,|y| < =10^8)":加入向量(x,y);
" Q x y l r (|x|,|y| < =10^8,1 < =L < =R < =T,其中T为已经加入的向量个数)询问第L个到第R个加入的向量与向量(x,y)的点积的最大值。
    集合初始时为空。

Input

输入的第一行包含整数N和字符s,分别表示操作数和数据类别;
    接下来N行,每行一个操作,格式如上所述。
    请注意s≠'E'时,输入中的所有整数都经过了加密。你可以使用以下程序
得到原始输入:
inline int decode (int x long long lastans) {
     return x ^ (lastans & Ox7fffffff);
}
function decode
begin
    其中x为程序读入的数,lastans为之前最后一次询问的答案。在第一次询问之前,lastans=0。

注:向量(x,y)和(z,W)的点积定义为xz+yw。

Output

对每个Q操作,输出一个整数表示答案。

将向量看作平面上的点,线段树维护上、下凸包,在凸包上三分可得到最优解。对线段树的每个区间,当区间内向量都已读入时计算凸包。
#include<cstdio>
#include<algorithm>
typedef long long i64;
char buf[],*ptr=buf,*pmx=buf+;
const i64 inf=1ll<<;
const int N=1e7;
int g(){
if(ptr==pmx)fread(ptr=buf,,,stdin);
return *ptr++;
}
int _(){
int x=,f=,c=g();
while(c<||c>)c=='-'&&(f=-),c=g();
while(c>&&c<)x=x*+c-,c=g();
return x*f;
}
int _c(){
int c=g();
while(c<'A'||c>'Z')c=g();
return c;
}
void maxs(i64&a,i64 b){if(a<b)a=b;}
void maxs(int&a,int b){if(a<b)a=b;}
void mins(int&a,int b){if(a>b)a=b;}
struct pos{
int x,y;
i64 operator()(pos a){
return i64(x)*a.x+i64(y)*a.y;
}
}mem[],*mp=mem;
pos operator-(pos a,pos b){
return (pos){a.x-b.x,a.y-b.y};
}
i64 operator*(pos a,pos b){
return i64(a.x)*b.y-i64(a.y)*b.x;
}
bool operator<(pos a,pos b){
return a.x!=b.x?a.x<b.x:a.y<b.y;
}
struct node{
pos*l,*r;
void init(int x,int y){
l=mp;
*mp++=(pos){x,y};
r=mp;
}
void ins(pos x){
if(mp>l&&mp[-].x==x.x)--mp;
while(mp-l>=&&(x-mp[-])*(mp[-]-mp[-])>=)--mp;
*mp++=x;
}
void init(node a,node b){
if(!a.l)*this=b;
else if(!b.l)*this=a;
else{
l=mp;
pos*ap=a.l,*bp=b.l;
while(ap!=a.r&&bp!=b.r){
if(*ap<*bp)ins(*ap++);
else ins(*bp++);
}
while(ap!=a.r)ins(*ap++);
while(bp!=b.r)ins(*bp++);
r=mp;
}
}
i64 find(pos x){
if(!l)return -1ll<<;
i64 v1,v2;
int L=,R=r-l-,M1,M2;
while(R-L>){
M1=L+R>>;
M2=M1+;
if(x(l[M1])<x(l[M2]))L=M1;
else R=M2;
}
for(v1=x(l[L++]);L<=R;++L)maxs(v1,x(l[L]));
return v1;
}
}us[],ds[];
bool d[];
int n,de,la=,x,y,l,r,id=;
int main(){
n=_();de=_c()!='E';
for(int i=;i<n;++i){
if(_c()=='A'){
x=_();y=_();++id;
if(de)x^=la,y^=la;
int w=id+;
us[w].init(x,y);
ds[w].init(x,-y);
d[w]=;
for(w>>=;w&&d[w<<^];w>>=){
us[w].init(us[w<<],us[w<<^]);
ds[w].init(ds[w<<],ds[w<<^]);
d[w]=;d[w<<^]=;
}
}else{
x=_();y=_();l=_();r=_();
if(de)x^=la,y^=la,l^=la,r^=la;
i64 ans=-1ll<<;
pos p1=(pos){x,y},p2=(pos){x,-y};
for(l+=,r+=;l^r^;l>>=,r>>=){
if(~l&)maxs(ans,us[l^].find(p1)),maxs(ans,ds[l^].find(p2));
if(r&)maxs(ans,us[r^].find(p1)),maxs(ans,ds[r^].find(p2));
}
printf("%lld\n",ans);
la=ans&0x7fffffff;
}
}
return ;
}

bzoj3533: [Sdoi2014]向量集的更多相关文章

  1. BZOJ3533 &lbrack;Sdoi2014&rsqb;向量集 【线段树 &plus; 凸包 &plus; 三分】

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

  2. BZOJ3533&colon;&lbrack;SDOI2014&rsqb;向量集&lpar;线段树&comma;三分&comma;凸包&rpar;

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

  3. BZOJ 3533&colon; &lbrack;Sdoi2014&rsqb;向量集&lpar; 线段树 &plus; 三分 &rpar;

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

  4. 【bzoj3533】&lbrack;Sdoi2014&rsqb;向量集 线段树&plus;STL-vector维护凸包

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

  5. bzoj 3533&colon; &lbrack;Sdoi2014&rsqb;向量集 线段树维护凸包

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

  6. bzoj 3533 &lbrack;Sdoi2014&rsqb;向量集 线段树&plus;凸包&plus;三分&lpar;&plus;动态开数组&rpar; 好题

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

  7. Sdoi2014 向量集

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

  8. P3309 &lbrack;SDOI2014&rsqb;向量集

    传送门 达成成就:一人独霸三页提交 自己写的莫名其妙MLE死都不知道怎么回事,照着题解打一直RE一个点最后发现竟然是凸包上一个点求错了--四个半小时就一直用来调代码了-- 那么我们只要维护好这个凸壳, ...

  9. SDOI 2014 向量集

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

随机推荐

  1. 用VisualC&plus;&plus;建立SOAP客户端应用&lpar;一&rpar;

    用VisualC++建立SOAP客户端应用(一) SoapSerializer对象用来构建一个向Web服务发送的SOAP消息.在与服务器连接前,SoapSerializer对象必须与SoapConne ...

  2. Java SE --- 自增自减

    关于变量的自增与自减运算.   1) int b = a++,作用是将a的值先赋给b,然后再让a自增1.   2) int b = ++a,作用是将a的值先自增1,然后将自增后的结果赋给b. 直接上例 ...

  3. Git 本地操作

    版权声明:数学是研究世界的本质,自然科学是研究上帝的意志,而计算机则是揣摩屌丝人类的意志   目录(?)[-] 命令 git config 增删改查 init clone add commit sta ...

  4. Android&lowbar;08手机联系人编码中SimpleAdapter的使用说明

    1. SimpleAdapter  adapter = new SimpleAdapter(this, list1,R.layout.my_layout, new String[] { "n ...

  5. eclipse使用配置

    eclipse设置工作空间为UTF-8(适应中文,避免乱码) windows---preference---general---workspace,修改textfile encoding eclips ...

  6. 启停无线网卡bat脚本

    @echo off color 2 title 启停无线网卡 echo 启动无线网卡=======>按1键 echo 关闭无线网卡=======>按2键 set /p n= if /i & ...

  7. MongoDB限制记录数

    MongoDB limit()方法 要限制 MongoDB 中返回的记录数,需要使用limit()方法. 该方法接受一个数字类型参数,它是要显示的文档数. 语法 limit()方法的基本语法如下: & ...

  8. JS学习之函数的属性和方法

  9. Nginx配置自签名的SSL证书&lpar;转载&rpar;

    要保证Web浏览器到服务器的安全连接,HTTPS几乎是唯一选择.HTTPS其实就是HTTP over SSL,也就是让HTTP连接建立在SSL安全连接之上. SSL使用证书来创建安全连接.有两种验证模 ...

  10. 01Trie树【p2420】 让我们异或吧

    Description 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生) ...