• HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)


    题目链接

    题意:中文题意。

    分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt》=0改成cnt>=2就行了,、

    但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于

    2,但是之前的那个线段加上现在的已经覆盖2次了。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <vector>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <algorithm>
      7 #define LL __int64
      8 #define lson l, mid, 2*rt
      9 #define rson mid+1, r, 2*rt+1
     10 const int maxn = 2000+10;
     11 using namespace std;
     12 int n;
     13 double y[maxn];
     14 struct node
     15 {
     16     int l, r, c;
     17     double cnt, lf, rf, more; //cnt还是代表覆盖的长度,增加了more代表两次及以上覆盖的长度
     18 }tr[4*maxn];
     19 struct Line
     20 {
     21     double x, y1, y2;
     22     int f;
     23 }line[maxn];
     24 bool cmp(Line a, Line b)
     25 {
     26     return a.x < b.x;
     27 }
     28 void build(int l, int r, int rt)
     29 {
     30     tr[rt].l = l; tr[rt].r = r;
     31     tr[rt].c = 0;  tr[rt].cnt = 0;
     32     tr[rt].more = 0;
     33     tr[rt].rf = y[r];  tr[rt].lf = y[l];
     34     if(l+1==r) return;
     35     int mid = (l+r)/2;
     36     build(l, mid, 2*rt);
     37     build(mid, r, 2*rt+1);
     38 }
     39 void calen(int rt)
     40 {
     41     if(tr[rt].c==0)
     42     {
     43         if(tr[rt].l+1==tr[rt].r)
     44         {
     45             tr[rt].cnt = 0; tr[rt].more = 0;
     46         }
     47         else
     48         {
     49             tr[rt].cnt = tr[2*rt].cnt+tr[2*rt+1].cnt;
     50             tr[rt].more = tr[2*rt].more+tr[2*rt+1].more;
     51         }
     52     }
     53     if(tr[rt].c==1)  //注意这一步是关键
     54     {
     55         tr[rt].cnt = tr[rt].rf-tr[rt].lf;
     56         if(tr[rt].l+1==tr[rt].r)  //因为没有注意是否到最后,错了一遍
     57         tr[rt].more = 0;
     58         else
     59         tr[rt].more = tr[2*rt].cnt + tr[2*rt+1].cnt; //为1的时候如果下面也有就加上
     60     }
     61     if(tr[rt].c>=2)
     62     {
     63         tr[rt].more = tr[rt].rf-tr[rt].lf;
     64         tr[rt].cnt = tr[rt].more;
     65     }
     66 }
     67 void update(int rt, Line e)
     68 {
     69     if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
     70     {
     71         tr[rt].c += e.f;
     72         calen(rt);
     73         return;
     74     }
     75     if(e.y2<=tr[2*rt].rf) update(2*rt, e);
     76     else if(e.y1>=tr[2*rt+1].lf) update(2*rt+1, e);
     77     else
     78     {
     79         Line tmp;
     80         tmp = e;
     81         tmp.y2 = tr[2*rt].rf; update(2*rt, tmp);
     82         tmp = e;
     83         tmp.y1 = tr[2*rt+1].lf; update(2*rt+1, tmp);
     84     }
     85     calen(rt);
     86 }
     87 int main()
     88 {
     89     int t, i, cnt;
     90     double x1, x2, y1, y2, ans;
     91     scanf("%d", &t);
     92     while(t--)
     93     {
     94         scanf("%d", &n);
     95         cnt = 1; ans = 0;
     96         for(i = 1; i <= n; i++)
     97         {
     98             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
     99             line[cnt].x = x1; line[cnt].y1 = y1;
    100             line[cnt].y2 = y2; line[cnt].f = 1;
    101             y[cnt++] = y1;
    102             line[cnt].x = x2; line[cnt].y1 = y1;
    103             line[cnt].y2 = y2; line[cnt].f = -1;
    104             y[cnt++] = y2;
    105         }
    106         sort(y+1, y+cnt);
    107         sort(line+1, line+cnt, cmp);
    108         cnt --;
    109         build(1, cnt, 1);
    110         update(1, line[1]);
    111         for(i = 2; i <= cnt; i++)
    112         {
    113             ans += tr[1].more*(line[i].x - line[i-1].x);
    114             update(1, line[i]);
    115         }
    116         printf("%.2lf
    ", ans);
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    联考20200604 T2 宝石
    联考20200604 T1 旅游
    联考20200603 T2 排列
    [HAOI2017]八纵八横
    联考20200603 T1 解码
    [POI2011]KON-Conspiracy
    CF917D Stranger Trees
    CF1278F Cards
    CF809E Surprise me!
    NOI2016 循环之美
  • 原文地址:https://www.cnblogs.com/bfshm/p/3901277.html
Copyright © 2020-2023  润新知