题目链接:【codeforces】678 F. Lena and Queries
#include
using namespace std ;
typedef long long LL ;
typedef pair < int , int > pii ;
#define getid( l , r ) l + r | ( l != r )
const int MAXN = 300005 ;
const int DEL = 1e9 + 7 ;
const LL INF = 2e18 ;
struct Line {
int k , b ;
Line () {}
Line ( int k , int b ) : k ( k ) , b ( b ) {}
LL f ( int x ) {
return 1LL * k * x + b ;
}
bool operator < ( const Line& a ) const {
return k != a.k ? k < a.k : b < a.b ;
}
} ;
vector < Line > T[MAXN << 1] ;
pii seg[MAXN] , op[MAXN] ;
int n , cnt ;
void add ( int L , int R , int k , int b , int l , int r ) {
int o = getid ( l , r ) , m = l + r >> 1 ;
if ( L <= l && r <= R ) T[o].push_back ( Line ( k , b ) ) ;
else {
if ( L <= m ) add ( L , R , k , b , l , m ) ;
if ( m < R ) add ( L , R , k , b , m + 1 , r ) ;
}
}
int check ( vector < Line >& a , int i , int j , int k ) {
return 1LL * ( a[i].b - a[j].b ) * ( a[k].k - a[i].k ) >= 1LL * ( a[i].b - a[k].b ) * ( a[j].k - a[i].k ) ;
}
void calc ( vector < Line >& T ) {
static int S[MAXN] , i , t ;
sort ( T.begin () , T.end () ) ;
for ( i = 0 , t = 0 ; i < T.size () ; ++ i ) {
while ( t && T[S[t]].k == T[i].k || t > 1 && check ( T , S[t - 1] , S[t] , i ) ) -- t ;
S[++ t] = i ;
}
vector < Line > nxt ;
for ( i = 1 ; i <= t ; ++ i ) {
nxt.push_back ( T[S[i]] ) ;
}
T = nxt ;
}
LL get_max_val ( int x , int o ) {
if ( !T[o].size () ) return -INF ;
int l = 0 , r = T[o].size () - 1 ;
while ( l < r ) {
int m = l + r >> 1 ;
if ( T[o][m].f ( x ) > T[o][m + 1].f ( x ) ) r = m ;
else l = m + 1 ;
}
return T[o][l].f ( x ) ;
}
LL query ( int x , int pos , int l , int r ) {
LL res = -INF ;
while ( l < r ) {
int o = getid ( l , r ) , m = l + r >> 1 ;
res = max ( res , get_max_val ( x , o ) ) ;
if ( pos <= m ) r = m ;
else l = m + 1 ;
}
res = max ( res , get_max_val ( x , getid ( l , r ) ) ) ;
return res ;
}
void solve () {
cnt = 0 ;
for ( int i = 1 ; i <= n << 1 ; ++ i ) T[i].clear () ;
for ( int i = 1 , c ; i <= n ; ++ i ) {
scanf ( "%d%d" , &c , &seg[i].first ) ;
if ( c == 1 ) scanf ( "%d" , &seg[i].second ) ;
else if ( c == 2 ) {
int x = seg[i].first ;
add ( x , i , seg[x].first , seg[x].second , 1 , n ) ;
seg[x].first = seg[i].first = DEL ;
} else op[++ cnt] = pii ( seg[i].first , i ) , seg[i].first = DEL ;
}
for ( int i = 1 ; i <= n ; ++ i ) {
if ( seg[i].first != DEL ) add ( i , n , seg[i].first , seg[i].second , 1 , n ) ;
}
for ( int i = 1 ; i <= n << 1 ; ++ i ) if ( T[i].size () ) {
calc ( T[i] ) ;
}
for ( int i = 1 ; i <= cnt ; ++ i ) {
LL res = query ( op[i].first , op[i].second , 1 , n ) ;
if ( res == -INF ) printf ( "EMPTY SET\n" ) ;
else printf ( "%lld\n" , res ) ;
}
}
int main () {
while ( ~scanf ( "%d" , &n ) ) solve () ;
return 0 ;
}