STL应用——神奇的set

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

你可能感兴趣的:(堆,STL)