转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23612967
【序言】以前一直仰慕着STL,趁着有空我就来研究一下。
【set的介绍】据说set可以完全代替优先队列(queue)。set的本质是一个红黑树。当然,set也可以用作去重,因为每一个数据只出现一次。如果要多次,可以用multiset,原理和set一样。
【头文件】include<set>
【基本操作】
q.insert(x)把元素x插入红黑树q中。
q.find(x)返回元素x的位置(注意返回的类型是set::iterator)
q,earse(x)把所有元素x删去。
q.earse(y)其中y的类型是set::iterator。把红黑树的第y个元素删去(只删一个)
q.begin()返回红黑树第一个元素的set::iterator类型
q.end()返回红黑树最后一个元素再之后的位置(相当于字符串中的“\0”)
q.size()返回红黑树的长度
*y 其中y的类型是set::iterator,返回红黑树的第y个元素
【注意】set::iterator的实质是一个指针。
【例题】
坐标轴上有N个矩形,保证下底面紧贴坐标轴。求出只被矩形覆盖一层的总面积。
输入:第一行是一个整数n,表示矩形数。接下来是n行,第(i+1)行给出3个整数h,l,r,表示第i个矩形的高,以及在坐标轴上的起始点和终点。
输出:被覆盖一层的总面积
样例输入:
2
1 1 4
2 2 3
样例输出:3
【分析】因为矩形下底面一定在x坐标上,我们每次只要维护一段区间的最大值和次大值几可。
【代码】
#include<cstdio> #include<algorithm> #include<set> #define N 200005 using namespace std; multiset<int,std::greater<int> > q; typedef set<int>::iterator it; typedef long long ll; struct arr{int x;bool p;int h;}a[N]; int n,i,top1,top2,h;long long ans; it it1,it2; bool cmp(arr a,arr b) { if (a.x!=b.x) return a.x<b.x; if (a.p) return 1;return 0; } int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d%d%d",&h,&a[i*2-1].x,&a[i*2].x); a[i*2-1].h=a[i*2].h=h;a[i*2-1].p=true; } n*=2; sort(a+1,a+n+1,cmp); q.insert(0); for (i=1;i<n;i++) { if (a[i].p) { q.insert(a[i].h); it1=q.begin();it2=it1++; top1=*it1;top2=*it2; ans+=ll(a[i+1].x-a[i].x)*ll(top2-top1); } else { q.erase(q.find(a[i].h)); if (q.size()==1) continue; it1=q.begin();it2=it1++; top1=*it1;top2=*it2; ans+=ll(a[i+1].x-a[i].x)*ll(top2-top1); } } printf("%I64d",ans); return 0; }