$ ext
又忘了线段树分治!! 显然维护一个上凸包 发现加点和删点可以变成限制存在时间 然后把点放在线段树上,线段树下标表示时间 加点时先把点按横坐标排序,然后就可以单调队列维护每个线段树节点的上凸包 询问再按斜率排序,这样可以弹点而不需要二分了 (O(n log n))
$ ext
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#define re register
#define ls (p << 1)
#define rs (ls | 1)
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int n, totp, totq, bz[N];
LL ans[N];
struct point{int x, y, st, ed;}P[N];
struct que{int a, b, ti, id;}Q[N];
inline bool cmpx(point u, point v){return u.x < v.x ? 1 : (u.x == v.x ? u.y > v.y : 0);}
inline bool cmp(que u, que v){return -1.0 * u.a / u.b < -1.0 * v.a / v.b;}
inline double slope(int u, int v)
{
if (P[u].x == P[v].x) return -INF;
return 1.0 * (P[u].y - P[v].y) / (P[u].x - P[v].x);
}
inline void read(int &x)
{
x = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar());
for(; isdigit(ch); x = (x<<3) + (x<<1) + (ch^48), ch = getchar());
}
vector<int> T[N * 4];
void update(int p, int l, int r, int tl, int tr, int x)
{
if (tl <= l && r <= tr)
{
int sz = T[p].size();
while (sz > 1 && slope(T[p][sz - 1], T[p][sz - 2]) < slope(T[p][sz - 1], x))
T[p].pop_back(), sz = T[p].size();
T[p].push_back(x);
return;
}
int mid = (l + r) >> 1;
if (tl <= mid) update(ls, l, mid, tl, tr, x);
if (tr > mid) update(rs, mid + 1, r, tl, tr, x);
}
LL query(int p, int l, int r, int x)
{
LL res = 0;
int sz = T[p].size();
while (sz > 1 && slope(T[p][sz - 1], T[p][sz - 2]) < -1.0 * Q[x].a / Q[x].b)
T[p].pop_back(), sz = T[p].size();
if (sz) res = 1LL * Q[x].a * P[T[p][sz - 1]].x + 1LL * Q[x].b * P[T[p][sz - 1]].y;
if (l == r) return res;
int mid = (l + r) >> 1;
if (Q[x].ti <= mid) return max(res, query(ls, l, mid, x));
return max(res, query(rs, mid + 1, r, x));
}
int main()
{
freopen("paper.in", "r", stdin), freopen("paper.out", "w", stdout);
read(n);
for(re int i = 1, ty; i <= n; i++)
{
read(ty);
if (ty == 3) ++totq, read(Q[totq].a), read(Q[totq].b), Q[totq].ti = i, Q[totq].id = totq;
else if (ty == 1)
bz[i] = ++totp, read(P[totp].x), read(P[totp].y), P[totp].st = i, P[totp].ed = n;
else read(ty), P[bz[ty]].ed = i;
}
sort(P + 1, P + totp + 1, cmpx), sort(Q + 1, Q + totq + 1, cmp);
for(re int i = 1; i <= totp; i++) update(1, 1, n, P[i].st, P[i].ed, i);
for(re int i = 1; i <= totq; i++)
if (!Q[i].ti) ans[Q[i].id] = 0; else ans[Q[i].id] = query(1, 1, n, i);
for(re int i = 1; i <= totq; i++) printf("%lld
", ans[i]);
}