• 星际争霸


    题目描述

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

    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
  • 相关阅读:
    201521123095 《Java程序设计》第11周学习总结
    201521123095 《Java程序设计》第10周学习总结
    201521123095 《Java程序设计》第9周学习总结
    201521123095 《Java程序设计》第8周学习总结
    201521123095 《Java程序设计》第7周学习总结
    201521123095 《Java程序设计》第6周学习总结
    201521123095 《Java程序设计》第5周学习总结
    网络软工15个人作业5
    软工网络15个人作业4
    集大通APP案例分析
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7263492.html
Copyright © 2020-2023  润新知