题目描述
玩星际争霸时,我们常常会不顾一切地大肆建造军队以扩充自己的战斗力。当我们快速建造军队时,我们总想知道这支部队的战斗力,以便设计好战略。你的任务是设计出一个能够快速回答一支部队的战斗力强弱的程序,部队的战斗力就是部队的人数。
-
C num,往编号为num的部队里加一个兵,如果当前还没有编号为num的部队,则建立这支部队并添加一个兵;
-
D num,代表编号为num的部队里一个兵牺牲了,如果此时部队里没有兵了,则删掉此部队,如果没有编号为num的部队,忽略此操作。
-
M x<y,表示将y里面的兵合并到x中,然后y消失,如果x或者y中任意一个数不存在,则忽略此次操作。
-
其中0<x,y,num<10^12
问:有n(<=600000)条命令,m<=100000组询问,每次询问请输出第k大值。
输入
第一行为一个整数n,表示后面的操作命令总数
从第二行开始的后n行,每行是一条操作命令
第n+2行是一个整数m,表示有m个提问
第n+3行有m个用一个空格隔开的树k1,k2,k3.。。。km,也就是提问站头里第ki强的部队编号。注意:可能ki=kj,也就是说战斗力第k强可能被问到两次
输出
输出jm行,每行输出一个战斗力第ki强的部队的士兵人数,如果没有第ki强的部队,则输出“NO”。
如果士兵人数从大到小分别为7,5,5,3,2,则战斗力第一强大的是7,第二,第三都为5,第四位3,第五为2
样例输入
5
C 4
C 8
M 8<4
D 4
C 5
3
1 2 3
样例输出
2
1
NO
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstdlib> #include<cstring> #include<queue> #include<stack> #include<ctime> using namespace std; const int maxn=600001; int n,m,size; struct student { long long key,x; }a[maxn]; struct node { long long key,rev,x; node *child[2]; }bst[maxn],*root; node *pos=bst; queue<node*>mem; void rotate(node* &r,bool t) { node *y=r->child[!t]; r->child[!t]=y->child[t]; y->child[t]=r; r=y; } void newnode(node* &r,int key) { if(mem.empty())r=pos++; else r=mem.front(),mem.pop(); r->key=key; r->x=1; r->rev=rand(); r->child[1]=r->child[0]=NULL; } void insert(node* &r,int key) { if(!r)newnode(r,key); else { bool t=r->key<key; insert(r->child[t],key); if(r->child[t]->rev<r->rev)rotate(r,!t); } } void delet(node* &r,int key) { if(!r)return; if(r->key==key) { if(r->child[0]&&r->child[1]) { bool t=r->child[0]->rev<r->child[1]->rev; rotate(r,t); delet(r->child[t],key); } else { mem.push(r); if(r->child[0])r=r->child[0]; else r=r->child[1]; } } else delet(r->child[r->key<key],key); } node* find(node* &r,int key) { if(!r)return NULL; if(r->key==key)return r; else return find(r->child[r->key<key],key); } void dfs(node* &r) { if(!r)return; a[++size].x=r->x; a[size].key=r->key; dfs(r->child[0]);dfs(r->child[1]); } bool cmp(const student a,const student b) { return a.x>b.x; } int main() { char s[2]; int i; long long j,k; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%s",s); if(s[0]=='C') { scanf("%lld",&j); node *y=find(root,j); if(y)y->x++; else insert(root,j); } if(s[0]=='D') { scanf("%lld",&j); node *y=find(root,j); if(y) { y->x--; if(y->x<=0)delet(root,j); } } if(s[0]=='M') { scanf("%lld",&j);getchar(); scanf("%lld",&k); node *x=find(root,j),*y=find(root,k); if(x!=NULL&&y!=NULL&&x!=y) { x->x+=y->x; delet(root,k); } } } dfs(root); sort(a+1,a+size+1,cmp); scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%lld",&j); if(j>size)printf("NO "); else printf("%lld ",a[j].x); } return 0; }