链接:https://www.nowcoder.com/acm/contest/93/L
时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
你们wyh学长小时候住在河边,因为周围的生态环境非常好,所以经常会有天鹅浮在湖面上,每只天鹅都长得不一样,它们偶尔排成一排,偶尔分散开,偶尔也会去其他河畔,wyh学长为了统计它们的个数,编了一个程序赋予它们一个“萌”值,但是这些天鹅很不听话,一会儿会从别的地方游过来一两只,一会儿又会在统计过程中游走一两只,现在请你帮他完成统计任务。
输入描述:
共有T(T<=10)组数据,每组数据第一行为两个数 N, M (N,M <= 500000),代表有N只天鹅和M次操作,接下来一行是N个数字,下面M行首先会输入一个字符串S,接着会有三类操作,如果S是“insert”,接着输入一个正整数a,代表插入一只“萌”值为a的天鹅,如果S是“delete”,接着输入一个正整数a,代表删除一只“萌”值为a的天鹅,如果S是“query”,接着输入一个正整数k,代表查询“萌”值第k大的天鹅。 萌值为[1,1000000000],并且保证一定存在第k大
输出描述:
对应每次询问,输出询问结果。
示例1
输入
1 5 4 6 4 2 9 1 query 2 insert 7 delete 6 query 2
输出
6 7
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct SPLAY
{
int val;
int num,size;
int f,l,r;
}a[2000000];
int root,size;
void show(int k)
{
if(k==-1)return;
printf("a[%d] father=%d val=%d num=%d size=%d l=%d r=%d\n",k,a[k].f,a[k].val,a[k].num,a[k].size,a[k].l,a[k].r);
show(a[k].l);
show(a[k].r);
}
void maintain(int k)
{
if(k==-1)return;
a[k].size=a[k].num;
if(a[k].l!=-1)a[k].size+=a[a[k].l].size;
if(a[k].r!=-1)a[k].size+=a[a[k].r].size;
}
void right_rotate(int k)
{
int p=a[k].f;
a[k].f=a[p].f;
if(a[p].f!=-1)
{
if(a[a[p].f].l==p)a[a[p].f].l=k;
else a[a[p].f].r=k;
}
else root=k;
a[p].l=a[k].r;
if(a[k].r!=-1)a[a[k].r].f=p;
a[k].r=p;
a[p].f=k;
maintain(p);
maintain(k);
}
void left_rotate(int k)
{
int p=a[k].f;
a[k].f=a[p].f;
if(a[p].f!=-1)
{
if(a[a[p].f].l==p)a[a[p].f].l=k;
else a[a[p].f].r=k;
}
else root=k;
a[p].r=a[k].l;
if(a[k].l!=-1)a[a[k].l].f=p;
a[k].l=p;
a[p].f=k;
maintain(p);
maintain(k);
}
void splay(long long k,long long f)
{
while(a[k].f!=f)
{
long long p=a[k].f;
if(a[p].f==f)
{
if(a[p].l==k)right_rotate(k);
else left_rotate(k);
}
else
{
long long ff=a[p].f;
if(p==a[ff].l&&k==a[p].l)right_rotate(p),right_rotate(k);
if(p==a[ff].l&&k==a[p].r)left_rotate(k),right_rotate(k);
if(p==a[ff].r&&k==a[p].r)left_rotate(p),left_rotate(k);
if(p==a[ff].r&&k==a[p].l)right_rotate(k),left_rotate(k);
}
}
}
void insert(int k,int val)
{
if(k<0)
{
a[size].val=val;
a[size].l=a[size].r=-1;
a[size].f=-1;
a[size].size=a[size].num=1;
root=size;
splay(size,-1);
size++;
return;
}
if(val<a[k].val)
{
if(a[k].l!=-1)insert(a[k].l,val);
else
{
a[size].val=val;
a[size].size=a[size].num=1;
a[size].l=a[size].r=-1;
a[size].f=k;
a[k].l=size;
splay(size,-1);
size++;
}
}
else if(val>a[k].val)
{
if(a[k].r!=-1)insert(a[k].r,val);
else
{
a[size].val=val;
a[size].size=a[size].num=1;
a[size].l=a[size].r=-1;
a[size].f=k;
a[k].r=size;
splay(size,-1);
size++;
}
}
else a[k].num++,a[k].size++,splay(k,-1);
maintain(k);
}
int search(int k,int x)
{
if(a[k].val>x)
{
if(a[k].l!=-1)return search(a[k].l,x);
}
else if(a[k].val<x)
{
if(a[k].r!=-1)return search(a[k].r,x);
}
splay(k,-1);
maintain(k);
return a[k].size-a[k].num+1-(a[k].r==-1?0:a[a[k].r].size);
}
int ask(int x)
{
int k=root;
while(1)
{
if(a[k].l!=-1&&x<=a[a[k].l].size)k=a[k].l;
else
{
int temp=(a[k].l==-1?0:a[a[k].l].size)+a[k].num;
if(x<=temp)return a[k].val;
x-=temp;
k=a[k].r;
}
}
return 0;
}
int askpre(int k,int val)
{
if(a[k].val>val)
{
if(a[k].l==-1)
{
long long p=a[k].f;
while(p!=-1&&k==a[p].l)k=p,p=a[p].f;
return p;
}
return askpre(a[k].l,val);
}
else if(a[k].val<val)
{
if(a[k].r==-1)return k;
return askpre(a[k].r,val);
}
if(a[k].l==-1)
{
long long p=a[k].f;
while(p!=-1&&k==a[p].l)k=p,p=a[p].f;
return p;
}
k=a[k].l;
while(a[k].r!=-1)k=a[k].r;
return k;
}
int asknex(int k,int val)
{
if(val<a[k].val)
{
if(a[k].l==-1)return k;
return asknex(a[k].l,val);
}
else if(val>a[k].val)
{
if(a[k].r==-1)
{
int p = a[k].f;
while( p!=-1&&k==a[p].r)k = p,p = a[p].f;
return p;
}
return asknex(a[k].r,val);
}
if(a[k].r==-1)
{
int p = a[k].f;
while( p!=-1&& k == a[p].r )k = p,p = a[p].f;
return p;
}
k=a[k].r;
while( a[k].l!=-1 )k = a[k].l;
return k;
}
void Delete(int val)
{
long long pre=askpre(root,val);
long long nex=asknex(root,val);
if(pre!=-1&&nex!=-1)
{
splay(pre,-1);
splay(nex,pre);
if(a[a[nex].l].num>1)a[a[nex].l].num--;
else a[nex].l=-1;
maintain(a[nex].l);
maintain(nex);
maintain(pre);
}
else if(pre!=-1&&nex==-1)
{
splay(pre,-1);
if(a[pre].r!=-1&&a[a[pre].r].val==val)
{
if(a[a[pre].r].num>1)a[a[pre].r].num--;
else a[pre].r=-1;
}
maintain(a[pre].r);
maintain(pre);
}
else if(pre==-1&&nex!=-1)
{
splay(nex,-1);
if(a[nex].l!=-1&&a[a[nex].l].val==val)
{
if(a[a[nex].l].num>1)a[a[nex].l].num--;
else a[nex].l=-1;
}
maintain(a[nex].l);
maintain(nex);
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
root=-1,size=0;
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
insert(root,x);
}
int tot=n;
while(m--)
{
char op[10];
int x;
scanf("%s%d",op,&x);
if(strcmp(op,"query")==0)printf("%d\n",ask(tot-x+1));
else if(strcmp(op,"insert")==0)insert(root,x),tot++;
else if(strcmp(op,"delete")==0)Delete(x),tot--;
}
//show(root);
}
return 0;
}