BZOJ 3533 向量集(凸包 + 二分 + 线段树)
题目:传送门
题意
1 < =N < =4*10^5
思路
思路参考 -> 戳
代码参考-> 戳
#include <bits/stdc++.h> #define mem(i, j) memset(i, j, sizeof(i)) #define rep(i, j, k) for(int i = j; i <= k; i++) #define pb push_back using namespace std; typedef long long LL; const LL inf = 0x3f3f3f3f3f3f3f3fLL; const int N = 400050; struct Point { LL x, y; Point() { } Point(LL x = 0, LL y = 0) : 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;} }; LL ans; char s[5], ch[5]; int n, tot, x, y, l, r; vector < Point > tmp[N << 2], up[N << 2], dw[N << 2]; void add(int rt, int l, int r, LL x, LL y, int pos) { tmp[rt].pb(Point(x, y)); if(pos == r) { sort(tmp[rt].begin(), tmp[rt].end()); for(int i = 0; i < tmp[rt].size(); i++) { while(up[rt].size() > 1 && ((up[rt][up[rt].size() - 1] - up[rt][up[rt].size() - 2]) ^ (tmp[rt][i] - up[rt][up[rt].size() - 1])) <= 0) up[rt].pop_back(); up[rt].pb(tmp[rt][i]); while(dw[rt].size() > 1 && ((dw[rt][dw[rt].size() - 1] - dw[rt][dw[rt].size() - 2]) ^ (tmp[rt][i] - dw[rt][dw[rt].size() - 1])) >= 0) dw[rt].pop_back(); dw[rt].pb(tmp[rt][i]); } } if(l == r) return ; int mid = (l + r) >> 1; if(pos <= mid) add(rt << 1, l, mid, x, y, pos); else add(rt << 1 | 1, mid + 1, r, x, y, pos); } void query(int rt, int l, int r, int L, int R, Point t) { if(L <= l && r <= R) { if(t.y >= 0) { int nowl = 1, nowr = up[rt].size() - 1, pos = 0; while(nowl <= nowr) { int mid = (nowl + nowr) >> 1; if(t * up[rt][mid] > t * up[rt][mid - 1]) { pos = mid; nowl = mid + 1; } else nowr = mid - 1; } ans = max(ans, t * up[rt][pos]); } else { int nowl = 1, nowr = dw[rt].size() - 1, pos = 0; while(nowl <= nowr) { int mid = (nowl + nowr) >> 1; if(t * dw[rt][mid] > t * dw[rt][mid - 1]) { pos = mid; nowl = mid + 1; } else nowr = mid - 1; } ans = max(ans, t * dw[rt][pos]); } return ; } int mid = (l + r) >> 1; if(L <= mid) query(rt << 1, l, mid, L, R, t); if(R > mid) query(rt << 1 | 1, mid + 1, r, L, R, t); } int main() { scanf("%d %s", &n, s); for(int i = 1; i <= n; i++) { scanf("%s %d %d", ch, &x, &y); if(s[0] != 'E') x ^= ans, y ^= ans; if(ch[0] == 'A') { tot++; add(1, 1, n, x, y, tot); } else { scanf("%d %d", &l, &r); if(s[0] != 'E') l ^= ans, r ^= ans; ans = -inf; query(1, 1, n, l, r, Point(x, y)); printf("%lld\n", ans); ans &= 0x7fffffff; } } return 0; }
一步一步,永不停息