日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++STL(set……)

發(fā)布時(shí)間:2023/12/3 c/c++ 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++STL(set……) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

set

底層實(shí)現(xiàn)是用紅黑樹。

set 建立

set<int> s; // 不可重,默認(rèn)升序 set<int,less> s; // 不可重,升序 set<int,greater> s; // 不可重,降序 multiset<int> s; // 可重集

set 也可以重載,利用結(jié)構(gòu)體實(shí)現(xiàn)。

重載方式同 priority_queue 。

set 插入及訪問

set<int>::iterator it; s.insert(x); // 插入元素 x s.begin(); // 最前面的迭代器 s.end(); // 最后一個(gè)元素之后的迭代器(實(shí)則空) s.rbegin(); // 最后一個(gè)迭代器 s.rend(); // 最前面的前一個(gè)迭代器pair<set<int>::iterator,bool> it=s.insert(x); if(it.second) { 插入成功 } else { 插入失敗 }

set 大小

s.size(); //返回容器中元素的數(shù)目 s.empty(); //判斷容器是否為空

set 的刪除操作

s.clear(); //清除所有元素 s.erase(it); //刪除 it 迭代器所指的元素,返回下一個(gè)元素的迭代器。 s.erase(l,r); //刪除區(qū)間 [l,r) 的所有元素,返回下一個(gè)元素的迭代器。 s.erase(x); //刪除容器中值為 x 的元素。

有的時(shí)候?yàn)榱吮苊鈩h除一個(gè)空的位置,在刪除是可以采用以下操作:

s.erase(s.find(*it));

set 的查找操作

s.find(x); //查找 x 元素,返回指向 x 元素的迭代器。 s.count(x); //返回容器中值為 x 的元素個(gè)數(shù)。對(duì) set 來說,要么是 0,要么是 1。對(duì) multiset 來說,值可能大于 1。 s.lower_bound(x); //返回第一個(gè) >=x 元素的迭代器 s.upper_bound(x); // 返回第一個(gè) >x 元素的迭代器。 s.equal_range(x); //返回容器中與 x 相等的上下限的兩個(gè)迭代器。上限是閉區(qū)間,下限是開區(qū)間,如 [l,r) 。

例題

P1081 [NOIP2012 提高組] 開車旅行

\(\text{set}\) 維護(hù)的部分:

給定數(shù)列 \(\{h\}\) (\(h_i\) 互不相同),定義兩點(diǎn) \(i,j(i<j)\) ,它們間的距離 \(dist(i,j)\)\(abs(h[i]-h[j])\)

對(duì)于每個(gè) \(i\) ,求出距離 \(i\) 最近、次近的 \(j(j>i)\) (若距離一致,\(h\) 越小的 \(j\) 距離 \(i\) 更近)。

考慮用 set 與 lower_bound 實(shí)現(xiàn)。

由于最后的幾個(gè)數(shù)找不到相應(yīng)的答案,因此要在 set 中提前加入極大、極小的值。

每次查詢 \(i\) 時(shí),查出比 \(h[i]\) 小的最大編號(hào),再訪問其向前、向后的迭代器即可。

部分代碼 h[0]=inf,h[n+1]=-inf; st.insert((Data){inf,0}),st.insert((Data){inf,0}); st.insert((Data){-inf,n+1}),st.insert((Data){inf,n+1}); for(int i=n;i;i--) {int ga,gb; // ga:max_max gb:max_minst.insert((Data){h[i],i});set<Data>::iterator it=st.lower_bound((Data){h[i],i});it--;int ln=(*it).num,lh=(*it).val;it++,it++;int rn=(*it).num,rh=(*it).val;it--;if(abs(lh-h[i])<=abs(rh-h[i])){gb=ln,it--,it--;if(abs(h[i]-(*it).val)<=abs(rh-h[i])) ga=(*it).num;else ga=rn;}else{gb=rn,it++,it++;if(abs(h[i]-(*it).val)>=abs(lh-h[i])) ga=ln;else ga=(*it).num;}fa[0][i][0]=ga;fa[0][i][1]=gb; }

priority_queue

應(yīng)用——對(duì)頂堆

維護(hù)

void tosame(int size_l) {while(qmin.size()<siz_l) qmin.push(qmax.top()),qmax.pop();while(qmin.size()>siz_l) qmax.push(qmin.top()),qmin.pop(); }void check() {while(qmin.top()>qmax.top()){qmin.pop(),qmin.push(y);qmax.pop(),qmax.push(x);} }

例題

P3644 [APIO2015]八鄰旁之橋

給出 \(2n\) 個(gè)點(diǎn),我們需要挑 \(1\) 個(gè)點(diǎn),使得這 \(2n\) 個(gè)點(diǎn)到該點(diǎn)的距離和最小。

先考慮 \(k=1\) 的情況,這其實(shí)是一個(gè)很經(jīng)典的結(jié)論,最優(yōu)位置顯然在中位數(shù)處(即排序后第 \(N\) 個(gè)點(diǎn)和第 \(N+1\) 個(gè)點(diǎn)之間的任意一點(diǎn))取得。

接下來是 \(K=2\) 的情況。此時(shí)集合點(diǎn)變成了兩個(gè),畫圖后會(huì)發(fā)現(xiàn),對(duì)于一條線段 \(AB\) 而言,選擇離這個(gè)線段中點(diǎn)較近的集合點(diǎn)結(jié)果最優(yōu)。

考慮將所有線段按 \(s_i+t_i\) 的順序排序,枚舉區(qū)域分界點(diǎn),則分界點(diǎn)左邊的區(qū)域前往左側(cè)集合點(diǎn),右邊的區(qū)域前往右側(cè)集合點(diǎn),問題變成了 \(K=1\) 的情況。

設(shè)集合大小為 \(s\),我們維護(hù)一個(gè)大根堆,存放前 \(\dfrac{s}{2}\) 小的元素,再維護(hù)一個(gè)小根堆,存放后 \(\dfrac{s}{2}\) 小的元素,則中位數(shù)為兩堆的堆頂(任取其一即可)。

代碼

include

reverse 翻轉(zhuǎn)

翻轉(zhuǎn)一個(gè) vector:

reverse(a.begin(),a.end());

翻轉(zhuǎn)一個(gè)數(shù)組:

reverse(a+1,a+n+1);

unique 去重

unique 用于“去除”容器中相鄰的重復(fù)元素(將重復(fù)的放在容器末尾),并返回去重后的尾地址。

由于去除的是相鄰的元素,一般將容器排好序后去重。

例如:

int a[10]={1,1,2,2,2,3,3,4,5,5}; int ans=unique(a,a+10)-a;

\(ans\) 的值為 \(5\)

vector 去重同理:

int m=unique(a.begin(),a.end())-a.begin();

rand_shuffle 隨機(jī)打亂

用法同 reverse ,經(jīng)常在模擬退火與爬山算法中使用。

next_permutation 下一個(gè)排列

若存在下一個(gè)排列,則返回值為 true ,否則為 false 。

lower_bound/upper_bound 二分

指定部分應(yīng)該是排好序的!

lower_bound 返回第一個(gè)大于等于 \(x\) 的元素的迭代器。

upper_bound 第一個(gè)大于 \(x\) 的元素的迭代器。

例如:

查找 int 數(shù)組中大于等于 \(x\) 的最小整數(shù)下標(biāo):

int i=lower_bound(a+1,a+n+1,x)-a;

在 vector 中查找小于等于 \(x\) 的最大整數(shù)(假設(shè)存在):

int i=*--upper_bound(a.begin(),a.end(),x);

總結(jié)

以上是生活随笔為你收集整理的C++STL(set……)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。