星际争霸

题目描述

玩星际争霸时,我们常常会不顾一切地大肆建造军队以扩充自己的战斗力。当我们快速建造军队时,我们总想知道这支部队的战斗力,以便设计好战略。你的任务是设计出一个能够快速回答一支部队的战斗力强弱的程序,部队的战斗力就是部队的人数。

  1. C num,往编号为num的部队里加一个兵,如果当前还没有编号为num的部队,则建立这支部队并添加一个兵;

  2. D num,代表编号为num的部队里一个兵牺牲了,如果此时部队里没有兵了,则删掉此部队,如果没有编号为num的部队,忽略此操作。

  3. M x<y,表示将y里面的兵合并到x中,然后y消失,如果x或者y中任意一个数不存在,则忽略此次操作。

  4. 其中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

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
long long hehe[700045],cnt;
struct node
{
    long long key,lev,num;
    node *child[2];
} Treap[700045],*root,*pos;
queue<node*>mem;
long long read()
{
    long long x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    ungetc(ch,stdin);
    return x*f;
}
void Newnode(node*&r,int key)
{
    if(mem.empty())
        r=pos++;
    else
        r=mem.front(),mem.pop();
    r->key=key;
    r->lev=rand();
    r->num=1;
    r->child[0]=r->child[1]=0;
}
void roll(node*&r,bool t)
{
    node*y=r->child[!t];
    r->child[!t]=y->child[t];
    y->child[t]=r;
    r=y;
}
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]->lev<r->lev)
            roll(r,!t);
    }
}
void Delete(node*&r,int key)
{
    if(!r)
        return;
    if(r->key==key)
    {
        if(r->child[0]&&r->child[1])
        {
            bool t=r->child[0]->lev<r->child[1]->lev;
            roll(r,t);
            Delete(r->child[t],key);
        }
        else
        {
            mem.push(r);
            if(r->child[0])
                r=r->child[0];
            else
                r=r->child[1];
        }
    }
    else
        Delete(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 print(node*r)
{
    if(!r)
        return;
    print(r->child[0]);
    if(r->num!=0)
        hehe[++cnt]=r->num;
    print(r->child[1]);
}
bool cmp(int x,int y)
{
    return x>y;
}
int main()
{
    int n,m,k1,k2;
    char lol[145];
    cin>>n;
    getchar();
    pos=Treap;
    for(int i=1; i<=n; i++)
    {
        char ch=getchar();
        while(ch!='C'&&ch!='D'&&ch!='M')
        ch=getchar();
        if(ch=='C')
        {
            long long s=read();
            node*p=find(root,s);
            if(p==0)
                insert(root,s);
            else
                p->num++;
        }
        if(ch=='D')
        {
            long long s=read();
            node*p=find(root,s);
            if(p==0)
                continue;
            else
            {
                p->num--;
                if(p->num==0)
                    Delete(root,s);
            }
        }
        if(ch=='M')
        {
            long long k1=read(),k2=read();
            node*p1=find(root,k1);
            node*p2=find(root,k2);
            if(p1==0||p2==0)
                continue;
            p1->num+=p2->num;
            Delete(root,k2);
        }
    }
    print(root);
    sort(hehe+1,hehe+1+cnt,cmp);
    cin>>m;
    for(int i=1; i<=m; i++)
    {
        long long s=read();
        if(s<=cnt)
            printf("%d
",hehe[s]);
        else
            printf("NO
");
    }
    return 0;
}
PEACE
原文地址:https://www.cnblogs.com/gshdyjz/p/7263492.html