• 星际争霸


    时间限制: 2 Sec  内存限制: 32 MB


    题目描述

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

    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
    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;
    }
  • 相关阅读:
    scanf与scanf_s的区别
    C语言输出时的各种%
    Windows下配置OpenGL环境
    C#高级进阶--重写函数
    Linux下安装国际版QQ (转)
    Linux Vim不明原因卡死解决办法
    iCamera App Kit 使用说明
    usb2.0高速视频采集之68013A寄存器配置说明
    iSensor APP 之 摄像头调试 OV5642 续集2
    iSensor APP 之 摄像头调试 OV9655 测试之二
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/6788768.html
Copyright © 2020-2023  润新知