2017.7.21 队测 新型操作系统

【题目描述】
小 M 需要一套管理系统,但是主流的操作系统都太臃肿。你需要帮小 M
开发一套支持以下操作的新操作系统:
1. 在某个进程内添加一个线程
2. 删除某个进程内的一个线程
3. 询问当前包含最多线程的进程号。若有多个,输出任意一个
初始时有 n 个不包含线程的进程,编号分别为 1~n。
【输入文件】
第一行两个整数 n m
接下来 m 行,每行以一个整数 p 开始:
若 p=1,则接下来一个整数 k,表示在 k 号进程内添加一个线程
若 p=2,则接下来一个整数 k,表示删除 k 号进程内的一个线程
若 p=3,则代表询问,你需要输出当前包含最多线程的进程号
【输出文件】
每个询问一行,每行包含一个整数,代表此次询问的答案
【样例输入】
2 5
1 1
3
1 2
1 2
3
【样例输出】
1
2
【数据范围】
30%的数据保证 n,m<=1000
90%的数据保证 n,m<=100000
100%的数据保证 n,m<=1000000 ; 删除线程的时候一定有线程可删

//90分 堆+优先队列
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#define maxn 1000000+10
using namespace std;

int n,m,p,k;

struct node
{
    int num;
    int xc;
}e[maxn];

priority_queue<node> q;

bool operator < (node a,node b)
{
    return a.xc<b.xc;
}

void do1()
{
    scanf("%d",&p); 
    e[p].xc++;
    q.push(e[p]);
    return;
}

void do2()
{
    scanf("%d",&p);
    e[p].xc--;
    q.push(e[p]);
    return; 
} 

void do3()
{
    node u=q.top();
    while(u.xc!=e[u.num].xc)
    {
        q.pop();
        u=q.top();
    }
    printf("%d\n",u.num);
    //printf("%d\n",u.xc);
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        e[i].num=i;
    }

    while(m--)
    {
        scanf("%d",&k);
        if(k==1) do1();
        if(k==2) do2();
        if(k==3) do3();
    }

    return 0;
}
//100 
#include <cstdio>
#include <cstring>
#include <cstdlib>

const int MAX_N = 1000009;
typedef int arr[MAX_N];

int n, m, i, k, op;
arr list, val, p, pos;

inline void swap(int &A, int &B) 
{
    static int t; 
    t = A; 
    A = B; 
    B = t;
}

int main() {
    scanf("%d%d", &n, &m);

    for (i=1; i<=n ;++i) list[i] = pos[i] = i;
    for (i=1; i<=n ;++i) val[i] = 0;
    p[0] = 1;
    for (i=1; i<=m ;++i) p[i] = n+1;

    while ( m-- ) {
        scanf("%d", &op);
        switch ( op ) {
            case 1 :
                scanf("%d", &k);
                ++val[k];
                swap(list[pos[k]], list[p[val[k]]-1]);
                swap(pos[k], pos[list[pos[k]]]);
                --p[val[k]];
                break;

            case 2 :
                scanf("%d", &k);
                if ( val[k]==0 ) {
                    fputs("cannto decrease\n", stderr);
                    exit(1);
                }
                swap(list[pos[k]], list[p[val[k]]]);
                swap(pos[k], pos[list[pos[k]]]);
                ++p[val[k]];
                --val[k];
                break;

            case 3 :
                printf("%d\n", list[n]);
                break;
        }
        /*
        printf("-- ");
        for (i=1; i<=n ;++i) printf("%d ", list[i]); puts("");
        */
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值