注意到线段树一个节点只有满了才会被用到,那时再建ConvexHull就行了。。。

#include <bits/stdc++.h>
using namespace std;
namespace my_useful_tools {
#define rep(_i, _k, _j) for(int _i = _k; _i <= _j; ++_i)
#define reu(_i, _k, _j) for(int _i = _k; _i < _j; ++_i)
#define red(_i, _k, _j) for(int _i = _k; _j <= _i; --_i)
#define foreach(_i, _s) for(typeof(_s.begin()) _i = _s.begin(); _i != _s.end(); ++_i)
#define pb push_back
#define mp make_pair
#define ipir pair<int, int>
#define ivec vector<int>
#define clr(t) memset(t, 0, sizeof t)
#define pse(t, v) memset(t, v, sizeof t)
#define brl puts("")
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define file_hza freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
#define file_gen(x) freopen(#x".in", "w", stdout);
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef double DB;
inline void pc(char c) { putchar(c); }
template<class T> inline T gcd(T a, T b) { return b == ? a : gcd(b, a % b); }
template<class T> inline void W(T p) { if(p < ) pc('-'), p = -p; if(p / != ) W(p / ); pc('' + p % ); }
template<class T> inline void Wn(T p) { W(p), brl; } template<class T> inline void W(T a, T b) { W(a), pc(' '), W(b); }
template<class T> inline void Wn(T a, T b) { W(a), pc(' '), Wn(b); }
template<class T> inline void W(T a, T b, T c) { W(a), pc(' '), W(b), pc(' '), W(c); }
inline char gchar() { char ret = getchar(); for(; ret == '\n' || ret == '\r' || ret == ' '; ret = getchar()); return ret; }
template<class T> inline void fr(T&ret) { char c = ' '; int flag = ; for(c = getchar(); c != '-' && !('' <= c && c <= ''); c = getchar());
if(c == '-') flag = -, ret = ; else ret = c - ''; for(c = getchar(); '' <= c && c <= ''; c = getchar()) ret = ret * + c - '';
ret = ret * flag;
}
inline int fr() { int x; fr(x); return x; }
template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); } template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
template<class T> inline T fast_pow(T base, T index, T mod = , T ret = ) {
for(; index; index >>= , base = base * base % mod) if(index & ) ret = ret * base % mod;
return ret;
}
};
using namespace my_useful_tools; const int maxNode = 1e7;
const int maxQueryNode = 4e5 + ;
const int maxSegNode = (maxQueryNode<<);
struct Point {
int x, y;
Point() {}
Point(int x, int y):x(x), y(y) {}
bool operator < (const Point&rhs) const {
return x < rhs.x || (x==rhs.x && y < rhs.y);
}
Point operator - (const Point&rhs) {
return Point(x-rhs.x, y-rhs.y);
}
} pool[maxNode], *loc = pool, P[maxQueryNode];
LL Dot(Point a, Point b) {
return (LL)a.x*b.x+(LL)a.y*b.y;
}
LL Cross(Point a, Point b) {
return (LL)a.x*b.y-(LL)a.y*b.x;
} struct ConvexHull {
Point *up, *dw;
int un, dn;
void buildConvexHull(Point*p, int sz) {
sort(p, p+sz);
up = loc;
int cnt = -;
reu(i, , sz) {
while (cnt > && Cross(p[i]-up[cnt-], up[cnt]-up[cnt-]) <= )
--cnt;
++cnt, up[cnt] = p[i];
}
loc += cnt+;
un = cnt+;
dw = loc;
cnt = -;
reu(i, , sz) {
while (cnt > && Cross(p[i]-dw[cnt-], dw[cnt]-dw[cnt-]) >= )
--cnt;
++cnt, dw[cnt] = p[i];
}
loc += cnt+;
dn = cnt+;
}
LL qMaxDot(Point p) {
LL ret = LLONG_MIN;
int l = , r = un-;
while (l <= r) {
if (r - l + <= ) {
for (register int i = l; i <= r; ++i) {
ret = max(ret, Dot(up[i], p));
}
break;
}
int mid = (l+r)>>;
if (Dot(up[mid], p) < Dot(up[mid+], p)) {
l = mid+;
} else {
r = mid;
}
}
l = , r = dn-;
while (l <= r) {
if (r - l + <= ) {
for (register int i = l; i <= r; ++i) {
ret = max(ret, Dot(dw[i], p));
}
break;
}
int mid = (l+r)>>;
if (Dot(dw[mid], p) < Dot(dw[mid+], p)) {
l = mid+;
} else {
r = mid;
}
}
// return ret;
// LL tmp = LLONG_MIN;
// for (int i = 0; i < un; ++i)
// tmp = max(tmp, Dot(up[i], p));
// for (int i = 0; i < dn; ++i)
// tmp = max(tmp, Dot(dw[i], p));
return ret;
}
} ch_pool[maxSegNode], *ch_loc = ch_pool; struct SegNode {
SegNode*lc, *rc;
ConvexHull*ch;
int l, r, sz;
SegNode() {
lc = rc = NULL;
ch = ch_loc++;
sz = ;
}
} sn_pool[maxSegNode], *sn_loc = sn_pool, *root; void buildSegTree(int l, int r, SegNode*&rt) {
if (rt == NULL) {
rt = sn_loc++;
rt->l = l, rt->r = r;
}
if (l == r) return ;
int mid = (l+r)>>;
buildSegTree(l, mid, rt->lc), buildSegTree(mid+, r, rt->rc);
} void addPoint(int pos, SegNode*rt) {
if (rt->l == rt->r) {
++rt->sz;
if (rt->sz == rt->r-rt->l+)
rt->ch->buildConvexHull(P+(rt->l), rt->sz);
return ;
}
int mid = (rt->l+rt->r)>>;
if (pos <= mid) addPoint(pos, rt->lc);
else addPoint(pos, rt->rc);
rt->sz = rt->lc->sz+rt->rc->sz;
if (rt->sz == rt->r-rt->l+)
rt->ch->buildConvexHull(P+(rt->l), rt->sz);
} Point qp;
LL Query(int ql, int qr, SegNode*rt) {
if (ql <= rt->l && rt->r <= qr) {
return rt->ch->qMaxDot(qp);
}
int mid = (rt->l+rt->r)>>;
LL ret = LLONG_MIN;
if (ql <= mid) ret = max(ret, Query(ql, qr, rt->lc));
if (mid < qr) ret = max(ret, Query(ql, qr, rt->rc));
return ret;
} int n;
bool e;
LL last_ans = 0LL; inline int decode(int x) {
if (e)
return x ^ (last_ans & 0x7fffffff);
else return x;
} void print_tree(SegNode*rt) {
if (rt == NULL) return ;
printf("%d %d %d\n", rt->l, rt->r, rt->sz);
print_tree(rt->lc);
print_tree(rt->rc);
} int main() {
fr(n), e=(gchar()!='E');
int x, y, ql, qr;
int cnt = ;
buildSegTree(, n, root);
while (n--) {
if (gchar() == 'A') {
x = decode(fr()), y = decode(fr());
P[++cnt] = Point(x, y);
addPoint(cnt, root);
} else {
x = decode(fr()), y = decode(fr());
ql = decode(fr()), qr = decode(fr());
// printf("%d %d %d %d\n", x, y, ql, qr);
qp = Point(x, y);
last_ans = Query(ql, qr, root);
printf("%lld\n", last_ans);
}
// print_tree(root);
} return ;
}

sdoi2014-向量集-线段树-二分斜率的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]

    题面 BZOJ传送门 思路 首先当然是推式子 对于一个询问点$(x_0,y_0$和给定向量$(x_1,y_1)$来说,点积这么表达: $A=x_0x_1+y_0y_1$ 首先肯定是考虑大小关系:$x_ ...

  7. bzoj4311向量(线段树分治+斜率优化)

    第二道线段树分治. 首先设当前向量是(x,y),剩余有两个不同的向量(u1,v1)(u2,v2),假设u1>u2,则移项可得,若(u1,v1)优于(u2,v2),则-x/y>(v1-v2) ...

  8. 【BZOJ4311】向量(线段树分治,斜率优化)

    [BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...

  9. bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...

随机推荐

  1. ubuntu内核及系统升级

    升级之前,需要先确认ubuntu当前系统版本,使用操作: root@Dy-JXQ-ubuntu-101:~# lsb_release -a No LSB modules are available. ...

  2. POJ - 2976 Dropping tests && 0/1 分数规划

    POJ - 2976 Dropping tests 你有 \(n\) 次考试成绩, 定义考试平均成绩为 \[\frac{\sum_{i = 1}^{n} a_{i}}{\sum_{i = 1}^{n} ...

  3. P3155 [CQOI2009]叶子的染色

    P3155 [CQOI2009]叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到 ...

  4. ROI align解释

    转自:blog.leanote.com/post/afanti.deng@gmail.com/b5f4f526490b ROI Align 是在Mask-RCNN这篇论文里提出的一种区域特征聚集方式, ...

  5. linux查看tomcat日志

    声明:以上内容均为转载,个人对这块知识搜罗之后放在一起,非原创,以后这块有问题还会继续添加. Tomcat 日志分为下面5类: catalina . 相当命令行输出日志 localhost . 相当于 ...

  6. LeetCode-330.Patching Array

    /** * nums的所有元素,假设最大能连续形成[1,sum] 当增加一个element的时候 * 会变成 [1,sum] [element+1,sum+element]两个区间,这两个区间有以下可 ...

  7. 【转载】wondows下wget的使用

    原文地址:http://www.cnblogs.com/Randy0528/archive/2011/10/21/2219831.html 感觉要放弃windows了,,,哎,,,, 下载window ...

  8. Javascript 常用的工具函数,更新中...

    1.时间戳转为格式化时间 /** * 时间戳转为格式化时间 * @Author chenjun * @DateTime 2017-11-10 * @param {[date]} timestamp [ ...

  9. 牛市必备的三个条件,A股现在还差几个

    1.国家政策 2.中美贸易 3.资金支持 A股变化如神! 自本月10日受美股大跌的影响后,A股先是随之震荡跳水,千股跌停:随后因高层力挺和政策支持而V型反转,集体涨停:接着上演过山车走势,有时涨得令人 ...

  10. SpringBoot与异步任务、定时任务、邮件任务

    异步任务 在需要开启异步的服务加上注解:@Async @Service public class AsyncService { //告诉SpringBoot这是一个异步任务,SpringBoot会自动 ...