题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=2028
题解
splay,貌似有更简单的算法?
开两个splay,一个记所有开始时间,一个记所有结束时间。由于一个时间为的会议需要冲掉所有满足:结束时间并且开始时间,因此这些会议必定是连续的,求出结束时间恰好和开始时间恰好的两个位置,splay区间删除这些位置即可。
代码
#include <cstdio>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=200000;
const int inf=0x3f3f3f3f;
struct node
{
node *son[2],*fa;
int val,size;
};
struct splay_tree
{
node tnode[maxn+10],*root;
int cnt;
int updata(node *x)
{
x->size=1;
if(x->son[0]!=NULL)
{
x->size+=x->son[0]->size;
}
if(x->son[1]!=NULL)
{
x->size+=x->son[1]->size;
}
return 0;
}
int t(node *x)
{
return x->fa->son[1]==x;
}
int rotate(node *x)
{
node *f=x->fa;
int k=t(x);
x->fa=f->fa;
if(f->fa!=NULL)
{
f->fa->son[t(f)]=x;
}
if(x->son[!k]!=NULL)
{
x->son[!k]->fa=f;
}
f->son[k]=x->son[!k];
f->fa=x;
x->son[!k]=f;
updata(f);
updata(x);
return 0;
}
int splay(node *x,node *y)
{
while(x->fa!=y)
{
node *f=x->fa;
if(f->fa==y)
{
rotate(x);
}
else if(t(x)==t(f))
{
rotate(f);
rotate(x);
}
else
{
rotate(x);
rotate(x);
}
}
if(y==NULL)
{
root=x;
}
return 0;
}
node* newnode(int val)
{
node *x=&tnode[++cnt];
x->son[0]=x->son[1]=x->fa=NULL;
x->size=1;
x->val=val;
return x;
}
int insert(node *x,node *y)
{
if(x==NULL)
{
root=y;
return 0;
}
if(y->val<x->val)
{
if(x->son[0]==NULL)
{
x->son[0]=y;
y->fa=x;
}
else
{
insert(x->son[0],y);
}
}
else
{
if(x->son[1]==NULL)
{
x->son[1]=y;
y->fa=x;
}
else
{
insert(x->son[1],y);
}
}
updata(x);
return 0;
}
int clear()
{
cnt=0;
insert(NULL,newnode(-inf));
insert(root,newnode(inf));
return 0;
}
int remove(node *x,node *y)
{
splay(x,NULL);
splay(y,x);
if(y->son[0]==NULL)
{
return 0;
}
int ans=y->son[0]->size;
y->son[0]=NULL;
return ans;
}
int getrank(node *x)
{
splay(x,NULL);
if(x->son[0]==NULL)
{
return 1;
}
return x->son[0]->size+1;
}
node* getlow(node *x,int val)
{
if(val<=x->val)
{
if(x->son[0]==NULL)
{
return NULL;
}
return getlow(x->son[0],val);
}
else
{
if(x->son[1]==NULL)
{
return x;
}
node *y=getlow(x->son[1],val);
if(y==NULL)
{
return x;
}
return y;
}
}
node* getkth(node *x,int k)
{
int sz=1;
if(x->son[0]!=NULL)
{
sz+=x->son[0]->size;
}
if(sz==k)
{
return x;
}
else if(sz>k)
{
return getkth(x->son[0],k);
}
else
{
return getkth(x->son[1],k-sz);
}
}
};
splay_tree st,ed;
int n;
char s[10];
int main()
{
n=read();
st.clear();
ed.clear();
for(int i=1; i<=n; ++i)
{
scanf("%s",s);
if(s[0]=='A')
{
int x=read(),y=read();
node *ednd=ed.getlow(ed.root,x),*stnd=st.getlow(st.root,-y);
int tot=st.root->size;
int ans=st.remove(stnd,st.getkth(st.root,tot-ed.getrank(ednd)+1));
ed.remove(ednd,ed.getkth(ed.root,tot-st.getrank(stnd)+1));
printf("%d\n",ans);
st.insert(st.root,st.newnode(-x));
ed.insert(ed.root,ed.newnode(y));
}
else
{
printf("%d\n",st.root->size-2);
}
}
return 0;
}