Pjudge #21636. 【PER #2】簡單資料結構
阿新 • • 發佈:2022-05-05
題面傳送門
一開始想到一個線段樹分治+可撤銷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]);} }