1. 程式人生 > >TOJ5705動態序列操作(STL or treap)

TOJ5705動態序列操作(STL or treap)

define 圖片 urn fine man 一個 alt 也不會 !=

傳送門:動態序列操作

在一個動態變化的序列中,完成以下基本操作:

(1)插入一個整數

(2)刪除一個整數

(3)查找序列中最大的數

(4)查找序列中最小的數

(5)求x的前驅(前驅定義為不大於x的序列中最大的數)

(6)求x的後繼(後繼定義為不小於x的序列中最小的數)

輸入

第一行為n,表示操作的次數,接下來有n行(n≤100000)

每行為以下操作之一:

(1)1 x:將x插入

(2)2 x:刪除x,x在序列中一定存在,若有多個相同值,只刪除一個。

(3)3:查找序列中最大的數

(4)4:查找序列中最小的數

(5)5 x:求x的前驅

(6)6 x:求x的後繼

數據保證結果一定存在,其中序列中整數的絕對值不超過107

輸出

對於op取3、4、5、6等操作,輸出相應的結果。

樣例輸入

10
1 2
3
1 5
4
1 10
2 5
1 3
6 8
1 11
5 3

樣例輸出

2
2
10
3

思路:

瞎搞:STL vector or 樹狀數組二分

正解:treap or splay(我也不會)

說說vector瞎搞吧,剛開始用set維護,需要另外有一個Map存是否刪完了,於是光榮超內存了。扔了幾天回頭拿vector寫了一發過了。

主要操作只有 insert:插入 earse:刪除 , upper_bound ,lower_bound 兩個對vector的二分查找。

lower_bound( begin,end,num):從數組的begin位置到end-1位置二分查找第一個大於或等於num的數字,找到返回該數字的地址

upper_bound( begin,end,num):從數組的begin位置到end-1位置二分查找第一個大於num的數字,找到返回該數字的地址

這裏只需要註意,“不大於”,“不小於”這幾個字眼即可。

代碼:

#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define
eps 1e-8 #define pi 3.141592653589793 vector<int>v; int main() { int _; for(scanf("%d",&_);_--;){ int cmd,x; scanf("%d",&cmd); if(cmd == 1){ scanf("%d",&x); v.insert(lower_bound(v.begin(),v.end(),x),x); }else if(cmd == 2){ scanf("%d",&x); v.erase(lower_bound(v.begin(),v.end(),x)); }else if(cmd == 3){ printf("%d\n",v[v.size()-1]); }else if(cmd == 4){ printf("%d\n",v[0]); }else if(cmd == 5){ scanf("%d",&x); vector<int>::iterator it = lower_bound(v.begin(),v.end(),x); if((*it) == x) printf("%d\n",x); else printf("%d\n",*(--it)); } else if(cmd == 6){ scanf("%d",&x); vector<int>::iterator it = upper_bound(v.begin(),v.end(),x); vector<int>::iterator itt = it; if(*(--itt) == x && itt!=v.begin()) printf("%d\n",x); else printf("%d\n",*it); } /*---test---*/ int f = 0; if(f == 1){ printf("zz :"); for(int i = 0 ; i < v.size() ; i ++) printf("%d ",v[i]); puts(""); } /*---test---*/ } return 0; }/* 10 1 2 3 1 5 4 1 10 2 5 1 3 6 8 1 11 5 3 144 1 1 2 1 1 1 1 3 2 3 1 3 1 10 2 10 1 10 1 10 1 11 6 10 6 10 5 10 6 9 6 -100 5 123123 */

技術分享圖片

600MS暴力做法

如果學完樹狀數組上二分,會更新一下樹狀數組二分的求解。

TOJ5705動態序列操作(STL or treap)