1. 程式人生 > >#6085. 「美團 CodeM 資格賽」優惠券

#6085. 「美團 CodeM 資格賽」優惠券

click alt gif ons ide hid problem != include

題目描述

用last[x]表示對x進行的上一次操作的位置,vis[x]表示x是否在大樓內。

Splay維護‘?‘的位置。

若x要進樓:

1.若x已在樓內,則去找last[x]到i之間是否有‘?‘,若有,則可以把這個‘?‘當做是上一個x出樓,反之則 出現錯誤。

2.若x不在樓內,標記x在樓內。

若x要出樓:

1.若x在樓內,標記x不在樓內。

2.若x不在樓內,相同的去找last[x]到i之間是否有‘?‘。

技術分享圖片
#include<complex>
#include<cstdio>
using namespace std;
const int N=5e5+7
; int n,sz,rot,ans=-1; int key[N],fat[N],son[N][2],siz[N],last[N]; bool vis[N]; int qread() { int x=0; char ch=getchar(); while(ch<0 || ch>9) { if(ch==I)return 1; if(ch==O)return 2; if(ch==?)return 3; ch=getchar(); }
while(ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();} return x; } void Update(int rt) { siz[rt]=siz[son[rt][0]]+siz[son[rt][1]]+1; } void Rotate(int x,int &rt) { int a=fat[x],b=fat[a],l=son[a][1]==x,r=l^1; if(a==rt)rt=x; else son[b][son[b][1]==a]=x; fat[son[x][r]]
=a;fat[a]=x;fat[x]=b; son[a][l]=son[x][r];son[x][r]=a; Update(a);Update(x); } inline void Splay(int x,int &rt) { while(x!=rt) { int a=fat[x],b=fat[a]; if(a!=rt) if((son[a][0]==x)^(son[b][0]==a)) Rotate(x,rt); else Rotate(a,rt); Rotate(x,rt); } } void Insert(int v,int k) { int fa=0; while(k && key[k]!=v) fa=k,k=son[k][key[k]<v]; k=++sz; key[k]=v;siz[k]=1;fat[k]=fa; if(fa)son[fa][key[fa]<v]=k; Splay(k,rot); } void Find(int x,int k) { while(son[k][key[k]<x] && x!=key[k]) k=son[k][key[k]<x]; Splay(k,rot); } void Delete(int x) { Find(x,rot); if(son[rot][0] && son[rot][1]) { int tmp=rot,k=son[rot][1]; rot=k; while(son[k][0])k=son[k][0]; siz[k]+=siz[son[tmp][0]]; fat[son[tmp][0]]=k;son[k][0]=son[tmp][0]; Splay(k,rot); } else rot=son[rot][0]+son[rot][1]; fat[rot]=0; } int GetNxt(int x) { Find(x,rot); if(key[rot]>x)return rot; int k=son[rot][1]; while(son[k][0])k=son[k][0]; return k; } int main() { scanf("%d",&n); int tmp,p,x; for(int i=1;i<=n;i++) { p=qread(); if(p==1) { x=qread(); if(vis[x]) { tmp=key[GetNxt(last[x])]; if(!tmp) { ans=i; break; } else Delete(tmp); } vis[x]=1; last[x]=i; } if(p==2) { x=qread(); if(!vis[x]) { tmp=key[GetNxt(last[x])]; if(!tmp) { ans=i; break; } else Delete(tmp); } vis[x]=0; last[x]=i; } if(p==3)Insert(i,rot); } printf("%d\n",ans); return 0; }
View Code

#6085. 「美團 CodeM 資格賽」優惠券