招生
Description
浙江理工大学招生,一开始有0名学生报考,现在有如下几种情况;
1.增加一名报考学生,报考学生成绩为x;
2.一名成绩为x的学生放弃报考。
3.从现在报考的学生来看,老师想知道如果要招生至少x名学生,需要将分数线最高设置为多少;
4.从现在报考的学生来看,如果分数线设置为x,能有几名学生被录取。
第一行先输入一个n,表示有n次操作或查询;
接下来n行,每行输入两个整数opt和x(用空格隔开):
如果opt为1,则增加一名报考学生,报考学生成绩为x;
如果opt为2,则表示一名成绩为x的学生放弃报考。
如果opt为3,从现在报考的学生来看,老师想知道如果要招生至少x名学生,需要将分数线最高设置为多少,输出最高分数线。
如果opt为4,从现在报考的学生来看,如果分数线设置为x,能有几名学生被录取,输出录取人数。
对于每个输出占一行。
n不超过50000;0<=x<=1000000;1<=k<=现在的学生数。
Input
第一行输入一个n,接下来n行,每行输出两个整数opt,x,用空格隔开
Output
对于每次输出, 输出一个整数占一行
Sample Input
18 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 2 8 3 2 3 3 3 4 3 5 4 8 4 9 4 7
Sample Output
11 10 9 7 4 4 5
HINT
题解:
平衡树Treap直接用
#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=1e6+8;
typedef long long LL;
typedef unsigned long long ULL;
//typedef pair<LL,LL> P;
const LL mod=1e9+7;
const ULL base=1e7+7;
using namespace std;
struct node{
int son[2];
int siz;
int key,w;
}a[maxn];
int tot=0;
int root=0,vis[maxn];
void up(int i){
a[i].siz=a[a[i].son[0]].siz+a[a[i].son[1]].siz+1;
}
void Rotate(int &i,int d){
int t=a[i].son[d];
a[i].son[d]=a[t].son[!d];
a[t].son[!d]=i;
up(i);up(t);
i=t;
}
void Insert(int &i,int key){
if(i==0){
i=++tot;
a[i].siz=1;a[i].key=key;a[i].w=rand();
return ;
}
a[i].siz++;
if(a[i].key>=key) {
Insert(a[i].son[0],key);
if(a[a[i].son[0]].w<a[i].w) Rotate(i,0);
}
else{
Insert(a[i].son[1],key);
if(a[a[i].son[1]].w<a[i].w) Rotate(i,1);
}
}
void Del(int &i,int key){
if(a[i].key==key){
if(a[i].son[0]*a[i].son[1]==0) {i=a[i].son[0]+a[i].son[1];return ;}
if(a[a[i].son[0]].w>a[a[i].son[1]].w){
Rotate(i,1);
Del(a[i].son[0],key);
}
else{
Rotate(i,0);
Del(a[i].son[1],key);
}
}
else if(a[i].key>key){
Del(a[i].son[0],key);
}
else{
Del(a[i].son[1],key);
}
up(i);
}
int Find(int i,int key){
if(i==0) return 1;
if(a[i].key>=key) return Find(a[i].son[0],key);
else return a[a[i].son[0]].siz+Find(a[i].son[1],key)+1;
}
int Search(int i,int rak){
if(a[a[i].son[0]].siz==rak-1) return a[i].key;
if(a[a[i].son[0]].siz>=rak) return Search(a[i].son[0],rak);
else return Search(a[i].son[1],rak-a[a[i].son[0]].siz-1);
}
int pre(int i,int key){
if(i==0) return -10000008;
if(a[i].key<key) return max(a[i].key,pre(a[i].son[1],key));
return pre(a[i].son[0],key);
}
int bhe(int i,int key){
if(i==0) return 10000008;
if(a[i].key>key) return min(a[i].key,bhe(a[i].son[0],key));
return bhe(a[i].son[1],key);
}
int main(){
int n;
freopen("data1.in","r",stdin);
freopen("data1.out","w",stdout);
scanf("%d",&n);
int opt,x;
int sum=0;
while(n--){
scanf("%d%d",&opt,&x);
if(opt==1){
Insert(root,x);
sum++;
vis[x]++;
}
if(opt==2){
if(vis[x]){
Del(root,x);
sum--;
vis[x]--;
}
}
if(opt==3){
printf("%d\n",Search(root,sum-x+1));
}
if(opt==4){
printf("%d\n",sum-Find(root,x)+1);
}
}
}