Pjudge #21636. 【PER #2】简单数据结构
题面传送门
一开始想到一个线段树分治+可撤销BIT的做法,大概就是先线段树分治变成只加不删,然后BIT维护一个凸的函数,加入每一个点的时候直接倍增就好了,时间复杂度\(O(n\log^2n)\),但是这个做法看上去很逊也没有任何的优化空间指不定随便一卡卡成40pts。
正确的做法是考虑\(u_x+v_x\leq u_y+v_y\)的条件,发现是\(u_x-u_y\leq v_x-v_y\),然后直接线段树上对\(u_x-u_y\)与\(v_y-v_x\)维护就好了,时间复杂度\(O(n\log n)\)
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define ll long long
#define db double
#define lb long db
#define N (250000+5)
#define M (220+5)
#define K (12+5)
#define mod 1000000007
#define Mod (mod-1)
#define eps (1e-9)
#define ull unsigned ll
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) (n*(x-1)+(y))
#define R(n) (rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using namespace std;const int Mx=2.5e5;
int n,m,k,O1,O2,x,y,z,Q;
namespace Tree{
#define ls now<<1
#define rs now<<1|1
int Ux[N<<3],Uy[N<<3],F[N<<3],Vx[N<<3],Vy[N<<3];multiset<int> P1[N<<1],P2[N<<1];
I void BD(){Me(Ux,0x3f);Me(Uy,0x3f);Me(F,0x3f);Me(Vx,0x3f);Me(Vy,0x3f);}
I void Up(int now){Vx[now]=min(Vx[ls],Vx[rs]);Vy[now]=min(Vy[ls],Vy[rs]);Ux[now]=min(Ux[ls],Ux[rs]);Uy[now]=min(Uy[ls],Uy[rs]);F[now]=min(min(F[ls],F[rs]),min(Uy[ls]+Vy[rs],Vx[ls]+Ux[rs]));}
I void Ins(int x,int op,int y,int l=-Mx,int r=Mx,int now=1){if(l==r){op^2?(P1[l+Mx].insert(y),Uy[now]=*P1[l+Mx].begin(),Ux[now]=Uy[now]+x):(P2[l+Mx].insert(y),Vy[now]=*P2[l+Mx].begin(),Vx[now]=Vy[now]-x);F[now]=max(Vx[now]+Ux[now],Vy[now]+Uy[now]);return;}int m=l+r>>1;x<=m?Ins(x,op,y,l,m,ls):Ins(x,op,y,m+1,r,rs);Up(now);}
I void Del(int x,int op,int y,int l=-Mx,int r=Mx,int now=1){if(l==r){op^2?(P1[l+Mx].erase(P1[l+Mx].LB(y)),P1[l+Mx].empty()?(Uy[now]=Ux[now]=1e9):(Uy[now]=*P1[l+Mx].begin(),Ux[now]=x+Uy[now])):(P2[l+Mx].erase(P2[l+Mx].LB(y)),P2[l+Mx].empty()?(Vy[now]=Vx[now]=1e9):(Vy[now]=*P2[l+Mx].begin(),Vx[now]=Vy[now]-x));F[now]=max(Vx[now]+Ux[now],Vy[now]+Uy[now]);return;}int m=l+r>>1;x<=m?Del(x,op,y,l,m,ls):Del(x,op,y,m+1,r,rs);Up(now);}
#undef ls
#undef rs
}
int main(){
freopen("1.in","r",stdin);freopen("1.out","w",stdout);
int i,j;scanf("%d",&Q);Tree::BD();while(Q--){scanf("%d%d%d%d",&O1,&O2,&x,&y);
if(O1^2) Tree::Ins(O2^2?x-y:y-x,O2,y);else Tree::Del(O2^2?x-y:y-x,O2,y);printf("%d\n",Tree::F[1]>1e9?-1:Tree::F[1]);}
}