题意:维护一个点集 向点集中进行插入删除和查询的操作 其中查询操作是 求 q*x+y的最大值
设 z=q*x+y 得到 y=-q*x+z 显然我们需要使得截距z最大 我们需要维护一个凸包 然后在通过三分在凸包上找到最大值
不过显然我们不能每次询问都去求一个凸包 那样复杂度是无法接受的
我们可以维护每个点出现的时间 然后把它挂在线段树上面 最后在遍历一遍线段树就行了 (类似于线段树分治的思想)
#include<bits/stdc++.h>
using namespace std;
int n,xx;
const int N = 3e5+10;
int op[N],r[N],cnt;
bool emp[N];
typedef long long ll;
ll Q[N],ans[N];
const ll inf = 6e18;
struct Point{
ll x,y;
Point(){}
Point(ll _x,ll _y){
x=_x;y=_y;
}
bool operator < (const Point &b)const{
if(x==b.x) return y<b.y;
return x<b.x;
}
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);
}
void in(){
scanf("%lld %lld",&x,&y);
}
}p[N],s[N];
vector<Point>T[N<<2];
#define pb push_back
ll cross(const Point &a,const Point &b){
return a.x*b.y-a.y*b.x;
}
void update(int id,int l,int r,int L,int R,int v){
if(L<=l&&R>=r){
T[id].pb(p[v]);
return;
}
int mid = l+r>>1;
if(L<=mid) update(id<<1,l,mid,L,R,v);
if(R>mid) update(id<<1|1,mid+1,r,L,R,v);
}
ll get(int id,const Point &a){
return Q[id]*a.x+a.y;
}
void query(int id,int tp){
int l=1,r=tp;
while(r-l>=3){
int mid1=(l+l+r)/3;
int mid2=(l+r+r)/3;
if(get(id,s[mid1])<get(id,s[mid2])) l=mid1;
else r=mid2;
}
for(int i = l; i <= r; i++) ans[id]=max(ans[id],get(id,s[i]));
}
void solve(int id,int l,int r){
int mid = l+r>>1;
if(l!=r){
solve(id<<1,l,mid);
solve(id<<1|1,mid+1,r);
}
if(!(int)T[id].size()) return;
sort(T[id].begin(),T[id].end());
int top=0;
for(auto v:T[id]){
while(top>1&&cross(v-s[top-1],s[top]-s[top-1])<=0) top--;
s[++top]=v;
}
for(int i = l; i <= r; i++){
if(op[i]==3&&!emp[i])
query(i,top);
}
}
int main(){
scanf("%d",&n);
for(int i = 1; i <= n; i++){
r[i]=n;
scanf("%d",&op[i]);
if(op[i]==1){
p[i].in();
cnt++;
}else if(op[i]==2){
scanf("%d",&xx);
cnt--;r[xx]=i;
}else{
if(cnt==0) emp[i]=true;
scanf("%lld",&Q[i]);
}
}
for(int i = 1; i <= n; i++){
ans[i]=-inf;
if(op[i]==1){
update(1,1,n,i,r[i],i);
}
}
solve(1,1,n);
for(int i = 1; i <= n; i++){
if(op[i]==3){
if(emp[i]) puts("EMPTY SET");
else printf("%lld\n",ans[i]);
}
}
return 0;
}