STL应用——神奇的set

来源:互联网 发布:刺客信条康纳 知乎 编辑:程序博客网 时间:2024/06/05 09:34

转载请注明: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 200005using 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;}

1 2
原创粉丝点击