zoukankan      html  css  js  c++  java
  • CSU 1292 Rectangles Intersection

      原题链接:http://122.207.68.93/OnlineJudge/problem.php?id=1292

      线段树+扫描线。这道题是典型的矩形面积并问题,乍一看109 * 109 * 10超了long long,但这个无关紧要,其实如果总面积>1018 可以直接判断肯定有相交的面积了,这么一来,就是裸模版题了,贴膜板:

      1 #include "cstdio"
      2 #include "iostream"
      3 #include "algorithm"
      4 #define lson cur<<1
      5 #define rson cur<<1|1
      6 using namespace std;
      7 typedef long long LL;
      8 const int maxn = 200000 + 5;
      9 const int root = 1;
     10 struct seg            //扫描线结构体
     11 {
     12     int x, y1, y2; //扫描线数据  x横坐标  y1,y2,上下顶点
     13     short flag;       //标记是进入的还是出来的(对于一个矩形所产生的两条扫描线来说)
     14     seg() {};
     15     seg(int a, int b, int c, short d):x(a), y1(b), y2(c), flag(d) {}
     16     inline friend bool operator <(seg a, seg b)
     17     {
     18         return a.x < b.x;    //用于sort
     19     }
     20 } ss[maxn];
     21 int m;               //扫描线总数
     22 int y[maxn];    //离散值-->实际值
     23 struct node               //线段树结构体 (加入的是扫描线(纵向))
     24 {
     25     int l, r, cover;      //左右范围(实际上没有用),cover:是否完全覆盖
     26     int yl, yr, len;   //实际范围和长度
     27     node() {}
     28     node(int a, int b, int c, int d, short f, int g)
     29     {
     30         l = a, r = b, yl = c, yr = d, cover = f, len = g;
     31     }
     32 } a[maxn << 2];
     33 inline void build(int cur, int l, int r)       //建立线段树
     34 {
     35     a[cur] = node(l, r, y[l], y[r], 0, 0);
     36     if (l+1 == r) return ;
     37     int mid = (l+r) >> 1;
     38     build(lson, l, mid);
     39     build(rson, mid, r);
     40 }
     41  
     42 inline void pushup(int cur)                          //计算当前cur结点覆盖的长度(纵向)
     43 {
     44     if (a[cur].cover > 0) a[cur].len = a[cur].yr - a[cur].yl;  //当前结点被完全覆盖
     45     else if (a[cur].l+1 == a[cur].r) a[cur].len = 0; //叶节点但已经被去除掉了(cover<=0)
     46     else  a[cur].len = a[lson].len + a[rson].len;    //自身未被完全覆盖,向子节点求助
     47 }
     48  
     49 inline void updata(int cur, seg b)                  //更新i.e加入边操作
     50 {
     51     if (b.y1 == a[cur].yl && b.y2 == a[cur].yr)
     52     {
     53         //被加入的边完全覆盖
     54         a[cur].cover += b.flag;                     //是否被抛弃
     55         pushup(cur);                                //计算长度
     56         return;
     57     }
     58     if (b.y2 <= a[rson].yl) updata(lson, b);
     59     else if (b.y1 >= a[lson].yr) updata(rson, b);
     60     else
     61     {
     62         seg tmp = b;                                //将b拆开付给lson rson
     63         tmp.y2 = a[lson].yr;
     64         updata(lson, tmp);
     65         tmp = b, tmp.y1 = a[rson].yl;
     66         updata(rson, tmp);
     67     }
     68     pushup(cur);
     69     return;
     70 }
     71 int main()
     72 {
     73     int t, n;
     74     int x1, x2, y1, y2;
     75     LL area;
     76     cin >> t;
     77     while(t--)
     78     {
     79         m = 0;
     80         scanf("%d", &n);
     81         area = 0;
     82         for (int i = 1; i <= n; i ++)
     83         {
     84             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
     85             area += (LL)(x2 - x1) * (LL)(y2 - y1);
     86             ss[++m] = seg(x1, y1, y2, 1), y[m] = y1;            //建立扫描线
     87             ss[++m] = seg(x2, y1, y2, -1), y[m] = y2;
     88         }
     89         if(area < 0 || area > 1000000000000000000ll)
     90         {
     91             cout << "Bad" << endl;
     92             continue;
     93         }
     94         sort(ss+1,ss+1+m);
     95         sort(y+1,y+1+m);          //离散化
     96  
     97         build(root, 1, m);                                                //建树
     98         LL sum(0);
     99         for (int i = 1; i < m; i++)                                    //依次加边
    100         {
    101             updata(root, ss[i]);
    102             sum += (LL)a[root].len * (LL)(ss[i+1].x - ss[i].x);   //计算此时面积
    103         }
    104         if(area == sum)
    105             puts("Good");
    106         else
    107             puts("Bad");
    108     }
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    view如何被添加到window上并显示出来
    事件分发机制
    绘制机制
    setContentView
    消息机制——handler
    布局文件是如何被解析的?
    Xamarin.ios引用第三方SDK
    Xamarin.ios——First APP
    UITextView 文本垂直居中
    从NavigationController 下的UITableView中移除 header
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/3097466.html
Copyright © 2011-2022 走看看