操作序列【STL模拟】

操作序列

题目描述

给出一个长度无限的数列,初始全部为零,有三种操作:

  • 增加操作:给下标为 t 的数加 c 。特别注意,如果在下标 [t−30,t+30] 内有不为零的数,增加操作无效。
  • 削减操作:让数列中下标最小的不为零数变为零。
  • 查询操作:查询数列中下标为 t 的数字是多少。

输入描述:

第一行包含一个整数 N,1≤N≤10^6,表示操作总数。

随后 N 行,每行由两个数字或一个数字组成。

若一行中有两个数字,分别代表增加操作的 t,c 。

若一行中只有数字-1,执行削减操作。

若一行中只有一个不为 -1的数字,则代表查询操作的数字 t。

保证t,c均为非负整数且在整形范围内。

输出描述:

削减操作时,先输出该数字,再变为零

若序列元素全为零,则削减操作无效,此时输出 "skipped"

查询时,输出该位置上的数

示例1

输入

7
140 1
120 2
100 3
120
100
-1
100

输出

0
3
3
0

示例2

输入

4
140 3
-1
140 1
-1

输出

3
1

示例3

输入

3
-1
-1
-1

输出

skipped
skipped
skipped

啊啊啊啊,写了我一晚上!自闭![t - 30, t + 30]区间内包括t!!!!!!想当然想成不包括t了QAQ……

而且STL操作生疏至极……

林俊杰说修炼爱情!我说修炼成仙!【手动滑稽qwq】


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;

typedef long long ll;

inline int read()
{
    int x = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}

const int maxN = 25;

struct node{
    int id, val;
    node() {}
    node(int a, int b): id(a), val(b) {}
    friend bool operator < (const node &n1, const node &n2) { return n1.id < n2.id; }
};

int getNum(char *s, int len)
{
    int ans = 0;
    for(int i = 0; i < len; ++ i )
        ans = ans * 10 + s[i] - '0';
    return ans;
}

char s[50], c[50];

multiset<node>st;
multiset<node>:: iterator it;

int main()
{
    int n; n = read();
    while(n -- )
    {
        gets(s);
        int len = strlen(s);
        if(s[0] == '-') //减操作
        {
            if(!st.empty())
            {
                it = st.begin();
                cout << (*it).val << endl;
                st.erase(it);
            }
            else
                cout << "skipped" << endl;
        }
        else
        {
            int pos = 0;
            while(s[pos] >= '0' && s[pos] <= '9')
                c[pos] = s[pos], ++ pos;
            c[pos] = '\0';
            int id = getNum(c, pos); //处理的位置

            if(pos < len) //加操作
            {
                int i;
                for(i = pos + 1, pos = 0; i < len; ++ i )
                    c[pos ++ ] = s[i];
                c[pos] = '\0';
                int val = getNum(c, pos);
                if(st.empty())
                {
                    st.insert(node(id, val));
                    continue;
                }
                it = st.lower_bound(node(id - 30, 0));
                if(it != st.end() && (*it).id <= id + 30 && (*it).val ) //范围内有非零数
                    continue;
                else
                    st.insert(node(id, val));
            }
            else //查询操作
            {
                it = st.find(node(id, 0));
                if(it != st.end())
                    cout << (*it).val << endl;
                else
                    cout << '0' << endl;
            }
        }
    }
    return 0;
}
/*
100
140 0
120 1
140 1
120 2
120
140
-1
-1
 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值