set,pair容器使用方法

题目链接:http://codeforces.com/gym/100989/problem/D

In this cafeteria, the N tables are all ordered in one line, where table number 1 is the closest to the window and table number N is the closest to the door.

Each time a group of X people enter the cafeteria, one of the cafeteria staff escorts the guests to the table with the smallest number of chairs greater than or equal to X chairs among all available tables. If there’s more than one such table, the guests are escorted to the table that is closest to the window. If there isn't any suitable table available, the group will leave the cafeteria immediately. A table is considered available if no one sits around it.

Eyad likes to help others and also likes to prove that he has learned something from the training of Master Hasan. Therefore, he decided to write a program that helps the cafeteria staff choose the right table for a newly arriving group.

Given the log file of who entered and who left the cafeteria, find the table at which a given group should sit.

Input

The first line of input contains two integers N and Q (1 ≤ N, Q ≤ 105), the number of tables in the cafeteria and the number of events in the log file.

The second line contains N integers, each represents the size of a table (number of chairs around it). The tables are given in order from 1 to N. The size of each table is at least 1 and at most 105.

Each of the following Q lines describes an event in one of the following formats:

- in X: means a group of X (1 ≤ X ≤ 105) people entered the cafeteria.

- out T: means the group on table number T (1 ≤ T ≤ N) just left the cafeteria, the table is now available. It is guaranteed that a group was sitting on this table (input is valid).

Initially, all tables are empty, and the log lists the events in the same order they occurred (in chronological order).

Output

For each event of the first type, print the number of the table on which the coming group should sit. If for any event a group cannot be escorted to any table, print  - 1 for that event.

Example

Input
4 7
1 2 6 7
in 4
in 1
in 3
in 5
out 1
out 4
in 7
Output
3
1
4
-1
4
这道题在比赛的时候感觉蛮容易是,但是没想到用我那种方法会在第十组数据超时,然后用二分法优化之后还是在第四十组数据那超时了,实在想不到什么优化的方法之后看别人的博客才知道这题是要用set来做的,果然还是学的太少了。
附上我比赛时的代码,以便以后看看可不可以优化出来。
代码1:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int ot[100050];
struct tb{
    int nb;
    int sum;
    int lg;
    bool operator <(const tb& t)const{
        if(sum!=t.sum)
        return sum<t.sum;
        else
        return nb<t.nb;
    }
}s[100050];
int bin(int l,int r,int sum){

    while (l <= r) {
        int mid = (l + r) / 2;
        if (s[mid].sum == sum) {
            if(s[mid].nb==1)
            return mid;
            else
            r=mid-1;
        }
        else if (s[mid].sum < sum) {
            l = mid + 1;
        }
        else {
            r = mid - 1;
        }
    }

    return l;
}
int main(){
    int n,t;
    int i,j;
    scanf("%d%d",&n,&t);
    for(i=0;i<n;i++){
        scanf("%d",&s[i].sum);
        s[i].nb=i+1;
        s[i].lg=0;
    }
    sort(s,s+n);
    char c[5];
    int a;
    while(t--){
        getchar();
        scanf("%s",&c);
        scanf("%d",&a);
        int lg1;
        if(c[0]=='i'){
            lg1=1;
            i=bin(0,n-1,a);
            for(;i<n&&lg1;i++){            
                if((s[i].lg==0||ot[s[i].nb]==1)&&s[i].sum>=a){
                    printf("%d\n",s[i].nb);            
                    s[i].lg=1;
                    ot[s[i].nb]=0;
                    lg1=0;
                    //printf("%d %d\n",s[i].lg,ot[s[i].nb]);
                }
            }
            if(lg1==1)
            printf("-1\n");
        }
        else if(c[0]=='o'){
            ot[a]=1;
        }
    }
    return 0;
}

用set后写的代码:

#include<cstdio>
#include<set>
using namespace std;
set<pair<int,int> > st1;
int s[100050];
int main(){
	int n,q;
	scanf("%d%d",&n,&q);
	int i,j;
	int a,b;
	for(i=1;i<=n;i++){
		scanf("%d",&s[i]);
		st1.insert(make_pair(s[i],i) );
	}
	char c[5];
	while(q--){
		getchar();
		scanf("%s%d",c,&a);
		if(c[0]=='i'){
			set<pair<int,int> >::iterator it;
			it=st1.lower_bound(make_pair(a,0));
			if(it==st1.end()){
				printf("-1\n");
			}
			else{
				printf("%d\n",it->second);
				st1.erase(it);
			}
		}
		else if(c[0]=='o'){
			st1.insert(make_pair(s[a],a));
		}
	}
	return 0;
}

set的主要用法(参考自https://www.cnblogs.com/omelet/p/6627667.html)

set的特性是,所有元素都会根据元素的键值自动排序,set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值。set不允许两个元素有相同的键值。

set的各成员函数列表如下:

1. begin()--返回指向第一个元素的迭代器

2. clear()--清除所有元素

3. count()--返回某个值元素的个数

4. empty()--如果集合为空,返回true

5. end()--返回指向最后一个元素的迭代器

6. equal_range()--返回集合中与给定值相等的上下限的两个迭代器

7. erase(迭代器)--删除集合中的元素

8. find()--返回一个指向被查找到元素的迭代器

9. get_allocator()--返回集合的分配器

10. insert(pair类型数据)--在集合中插入元素

11. lower_bound(pair类型数据)--返回指向大于(或等于)某值的第一个元素的迭代器

12. key_comp()--返回一个用于元素间值比较的函数

13. max_size()--返回集合能容纳的元素的最大限值

14. rbegin()--返回指向集合中最后一个元素的反向迭代器

15. rend()--返回指向集合中第一个元素的反向迭代器

16. size()--集合中元素的数目

17. swap()--交换两个集合变量

18. upper_bound()--返回大于某个值元素的迭代器

19. value_comp()--返回一个用于比较元素间的值的函数

猜你喜欢

转载自www.cnblogs.com/cglongge/p/9273169.html