Sdoi2014 向量集
题解:
码力太差重构之后才$A……$
首先求向量点积最大很容易想到凸包,
设已知$(x_0,y_0)$,求$(x,y)$满足$(x,y)*(x_0,y_0)>=(x',y')*(x_0,y_0)$
设$(x,y)*(x_0,y_0)=c$
那么$x*x_0+y*y_0=c$,$y=\frac(-x_0,y_0)*x+\frac(c,x_0)$
所以$x_0>0$时,$b$取最大,维护上凸包;
$x_0<0$时,$b$取最小,维护下凸包。
其实$x_0=0$不需要单独维护,放到任意一堆里二分都行。
由于询问与时间序有关,我们可以按时间建线段树,
每个节点挂一个凸包。
每次询问时从对应凸包二分查最大点积。
插入时并不需要每插一个点就把这个凸包拆开重构,
只需要在子树插满,即$r=x$时建立凸包即可。
代码:
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const double eps = 1e16;
int n,tot;
ll ans;
char s0[],s[];
struct Point
{
ll x,y;
Point(){}
Point(ll x,ll y):x(x),y(y){}
ll operator * (const Point&a)const{return x*a.x+y*a.y;}
ll operator ^ (const Point&a)const{return y*a.x-x*a.y;}
Point operator + (const Point&a)const{return Point(x+a.x,y+a.y);}
Point operator - (const Point&a)const{return Point(x-a.x,y-a.y);}
bool operator < (const Point&a)const{return x==a.x?y<a.y:x<a.x;}
};
vector<Point>tmp[N<<],c1[N<<],c2[N<<];
struct segtree
{
void insert(int l,int r,int u,ll x,ll y,int z)
{
tmp[u].push_back(Point(x,y));
if(z==r)
{
sort(tmp[u].begin(),tmp[u].end());
for(int i=;i<tmp[u].size();i++)
{
while(c1[u].size()>&&((c1[u][c1[u].size()-]-c1[u][c1[u].size()-])^(tmp[u][i]-c1[u][c1[u].size()-]))<=)c1[u].pop_back();
c1[u].push_back(tmp[u][i]);
while(c2[u].size()>&&((c2[u][c2[u].size()-]-c2[u][c2[u].size()-])^(tmp[u][i]-c2[u][c2[u].size()-]))>=)c2[u].pop_back();
c2[u].push_back(tmp[u][i]);
}
}
if(l==r)return ;
int mid = (l+r)>>;
if(z<=mid)insert(l,mid,u<<,x,y,z);
else insert(mid+,r,u<<|,x,y,z);
}
void query(int l,int r,int u,Point p,int ql,int qr)
{
if(l==ql&&r==qr)
{
if(p.y>=)
{
int L = ,R = c1[u].size()-,as = ;
while(L<=R)
{
int mid = (L+R)>>;
if(p*c1[u][mid]>p*c1[u][mid-])as=mid,L=mid+;
else R=mid-;
}
ans=max(ans,p*c1[u][as]);
}else
{
int L = ,R = c2[u].size()-,as = ;
while(L<=R)
{
int mid = (L+R)>>;
if(p*c2[u][mid]>p*c2[u][mid-])as=mid,L=mid+;
else R=mid-;
}
ans=max(ans,p*c2[u][as]);
}
return ;
}
int mid = (l+r)>>;
if(qr<=mid)query(l,mid,u<<,p,ql,qr);
else if(ql>mid)query(mid+,r,u<<|,p,ql,qr);
else query(l,mid,u<<,p,ql,mid),query(mid+,r,u<<|,p,mid+,qr);
}
}tr;
int main()
{
scanf("%d%s",&n,s0);
for(int x,y,l,r,i=;i<=n;i++)
{
scanf("%s%d%d",s,&x,&y);
if(s0[]!='E')x^=ans,y^=ans;
if(s[]=='A')
{
tot++;
tr.insert(,n,,x,y,tot);
}else
{
scanf("%d%d",&l,&r);
if(s0[]!='E')l^=ans,r^=ans;
ans=-inf;
tr.query(,n,,Point(x,y),l,r);
printf("%lld\n",ans);
ans&=0x7fffffff;
}
}
return ;
}
Sdoi2014 向量集的更多相关文章
- BZOJ 3533: [Sdoi2014]向量集( 线段树 + 三分 )
答案一定是在凸壳上的(y>0上凸壳, y<0下凸壳). 线段树维护, 至多N次询问, 每次询问影响O(logN)数量级的线段树结点, 每个结点O(logN)暴力建凸壳, 然后O(logN) ...
- BZOJ3533 [Sdoi2014]向量集 【线段树 + 凸包 + 三分】
题目链接 BZOJ3533 题解 我们设询问的向量为\((x_0,y_0)\),参与乘积的向量为\((x,y)\) 则有 \[ \begin{aligned} ans &= x_0x + y_ ...
- bzoj3533: [Sdoi2014]向量集
Description 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);" Q x y l r (|x| ...
- 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| & ...
- P3309 [SDOI2014]向量集
传送门 达成成就:一人独霸三页提交 自己写的莫名其妙MLE死都不知道怎么回事,照着题解打一直RE一个点最后发现竟然是凸包上一个点求错了--四个半小时就一直用来调代码了-- 那么我们只要维护好这个凸壳, ...
- SDOI 2014 向量集
[SDOI2014]向量集 题目描述 维护一个向量集合,在线支持以下操作: - "A x y (|x|,|y| < =10^8)":加入向量(x,y); - " Q ...
随机推荐
- Scipy-数值计算库
Scipy在Numpy的基础上则加了众多的数学计算,科学计算以及工程计算中常用的模块,例如线性代数,常微分方程的数值求解,信号处理,图像处理,系数矩阵等.在本章中,将通过实例介绍Scipy中常用的的一 ...
- vue移动端开发全家桶
一句命令搞定全家桶: npm install vue-router vue-resource vuex --save main.js配置: import Vue from 'vue' impor ...
- Educational Codeforces Round 24 D
Alice and Bob got very bored during a long car trip so they decided to play a game. From the window ...
- java基本数据类型在栈中怎么存放的?
参考地址:https://www.zhihu.com/question/24747160 问:int a = 3; 首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟 ...
- 转--oracle查看允许的最大连接数和当前连接数等信息
两个参数间的关系:sessions=1.1*processes+5 目前总结的语句,在查看数据的连接情况很有用,写完程序一边测试代码一边查看数据库连接的释放情况有助于分析优化出一个健壮的系统程序来. ...
- Linux下cpu过高问题排查
原文地址:https://blog.csdn.net/chenjunan888/article/details/80447800 在服务器报cpu过高时,可使用以下命令,快速导出堆栈信息,以方便查看具 ...
- pyton 基础,运算符及字符类型。
一.python运算符: 二.数据类型: 1.数字: int :整型 32位机器上一个整数取值范围为-2**31~2**31-1即-2147483648~2147483647 64位机器上一个整数取 ...
- ISCSI存储
slave-147作为服务端 需要安装的软件 [root@slave-147 ~]# yum install -y scsi-target-utils slave-148和slave-149作为客户端 ...
- JS执行保存在数据库中的JS代码
function createScript(script) { var myScript = document.createElement("script"); myScript. ...
- P1482 Cantor表(升级版)
题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 2/2 2/3 2/4 … ...