• 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
  • 相关阅读:
    Java实现各种内部排序算法
    Java实现堆排序(大根堆)
    Java对象的序列化和反序列化
    Java实现链式存储的二叉查找树(递归方法)
    337. House Robber III(包含I和II)
    318. Maximum Product of Word Lengths
    114. Flatten Binary Tree to Linked List
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    96. Unique Binary Search Trees(I 和 II)
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/3097466.html
Copyright © 2020-2023  润新知