STL容器 set
阿新 • • 發佈:2018-09-15
com click push 不可 -- 內存拷貝 iter i++ 系統
基礎:
set是關聯容器,set中每個元素的值都是唯一的,系統能夠根據元素的值自動進行排序。set中數元素的值並不能直接被改變。STL中還有一些標準關聯容器multiset、map 和 multimap 等,這些關聯容器內部均是采用紅黑樹實現的。
set特點:
①、map和set的插入刪除效率比其他序列容器高。
原因:set中所有元素都是以節點的方式來存儲的,其節點結構和鏈表類似,指向父節點和子節點。所以,在插入和刪除時不需要做內存拷貝和內存移動,故而提高了效率。
②、每次insert之後,以前保存的iterator不會失效。
原因:叠代器iterator在set中就相當於指向節點的指針,只要內存不變,那這個iterator 就不會失效。相對於vector來說,每一次的刪除和插入之後,指針都有可能失效,調用push_back在尾部插入的時候情況也是如此。因為為了保證內部數據的連續存放,iterator指向的那塊內存在插入和刪除的過程中可能已經被其他內存覆蓋或者內存已經被釋放掉了。即使是push_back的時候,容器內部空間可能不夠,需要一塊新的更大的內存,只能把以前的內存釋放掉,申請更大的內存,復制已有的數據元素都新的內存中,最後把需要插入的元素放到最後,那麽以前的內存指針自然就不可用了。特別是在和find、erase等操作一起使用的時候,一定要註意:不要使用失效的iterator。
③、
使用方法:
例題 :
ACM-ICPC 2018 徐州賽區網絡預賽 G Trace
#include<bits/stdc++.h> using namespace std; typedef long long ll; struct point{ int x,y; bool operator < (const point & _point)const{ return x < _point.x; } }tot[50005]; set<point> M; int n,a,b; int main() { scanf(View Code"%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&tot[i].x,&tot[i].y); } M.clear(); ll ans = 0; ans += tot[n].x;ans += tot[n].y; M.insert(tot[n]); for(int i=n-1;i>=1;i--) { if(M.lower_bound(tot[i])==M.end()){ set<point>::iterator it = M.end(); it--; point temp = *(it); ans += tot[i].y; ans += tot[i].x - temp.x; } else if(M.lower_bound(tot[i])==M.begin()){ point temp = *M.begin(); ans += tot[i].x; ans += tot[i].y - temp.y; } else{ set<point>::iterator it = (M.lower_bound(tot[i])); point temp1 = *it; it--; point temp = *it; ans += tot[i].y - temp1.y; ans += tot[i].x - temp.x; } M.insert(tot[i]); } cout<<ans<<endl; }
參考
STL容器 set