1. 程式人生 > >set,pair容器使用方法

set,pair容器使用方法

ast -- const mas span tps gym follow type

題目鏈接: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()--返回一個用於比較元素間的值的函數

set,pair容器使用方法