• HDU 4052 Adding New Machine (线段树+离散化)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4052

    初始给你w*h的矩阵,给你n个矩形(互不相交),按这些矩形尺寸把初始的矩形扣掉,形成一个新的'矩形'。然后给你1*m大小的矩形,问这个矩形在新'矩形'中有多少种放法。

    一开始没想法==,然后看了看题解,说是线段树做的。

    要是m为1的话,那答案就是剩下的面积了。

    不为1的话,可以把n个矩形的面积扩展一下(我是向右扩展),比如x1 y1 x2 y2 的矩形扣掉,就相当于x1  y1  x2+m-1  y2的地方扣掉了,这种是x轴的情况。那么y轴的情况就是x1 y1 x2  y2+m-1。最左边也要扣掉,比如x轴就是0 0 m - 1 h。所以最后就是算剩下的面积了。(我的方法比较笨,就是x轴一个线段树扫一下,y轴一个线段树扫一下)

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <map>
      6 using namespace std;
      7 const int MAXN = 1e5 + 10;
      8 typedef long long LL;
      9 LL fab(LL a) {
     10     return (a > 0 ? a : -a);
     11 }
     12 struct data {
     13     int ll , rr , flag , l , r , h;
     14     bool operator <(const data &cmp) const {
     15         return h < cmp.h;
     16     }
     17 }line1[MAXN] , line2[MAXN];
     18 struct segtree {
     19     LL val;
     20     int l , r , add;
     21 }T1[MAXN * 3] , T2[MAXN * 3];
     22 LL x[MAXN] , y[MAXN];
     23 map <int , int> mp1 , mp2;
     24 int f1 , f2;
     25 
     26 inline void add1(LL num) {
     27     if(!mp1[num]) {
     28         x[++f1] = num;
     29         mp1[num] = 1;
     30     }
     31 }
     32 
     33 inline void add2(LL num) {
     34     if(!mp2[num]) {
     35         y[++f2] = num;
     36         mp2[num] = 1;
     37     }
     38 }
     39 
     40 void pushupx(int p) {
     41     if(T1[p].add) {
     42         T1[p].val = x[T1[p].r] - x[T1[p].l];
     43     }
     44     else if(T1[p].r - T1[p].l == 1) {
     45         T1[p].val = 0;
     46     }
     47     else {
     48         T1[p].val = T1[p << 1].val + T1[(p << 1)|1].val;
     49     }
     50 }
     51 
     52 void pushupy(int p) {
     53     if(T2[p].add) {
     54         T2[p].val = y[T2[p].r] - y[T2[p].l];
     55     }
     56     else if(T2[p].r - T2[p].l == 1) {
     57         T2[p].val = 0;
     58     }
     59     else {
     60         T2[p].val = T2[p << 1].val + T2[(p << 1)|1].val;
     61     }
     62 }
     63 
     64 void buildx(int p , int l , int r) {
     65     int mid = (l + r) >> 1;
     66     T1[p].l = l , T1[p].r = r , T1[p].val = T1[p].add = 0;
     67     if(r - l == 1) {
     68         return ;
     69     }
     70     buildx(p << 1 , l , mid);
     71     buildx((p << 1)|1 , mid , r);
     72 }
     73 
     74 void buildy(int p , int l , int r) {
     75     int mid = (l + r) >> 1;
     76     T2[p].l = l , T2[p].r = r , T2[p].val = T2[p].add = 0;
     77     if(r - l == 1) {
     78         return ;
     79     }
     80     buildy(p << 1 , l , mid);
     81     buildy((p << 1)|1 , mid , r);
     82 }
     83 
     84 void updatex(int p , int l , int r , int add) {
     85     int mid = (T1[p].l + T1[p].r) >> 1;
     86     if(T1[p].l == l && T1[p].r == r) {
     87         T1[p].add += add;
     88         pushupx(p);
     89         return ;
     90     }
     91     if(r <= mid) {
     92         updatex(p << 1 , l , r , add);
     93     }
     94     else if(l >= mid) {
     95         updatex((p << 1)|1 , l , r , add);
     96     }
     97     else {
     98         updatex(p << 1 , l , mid , add);
     99         updatex((p << 1)|1 , mid , r , add);
    100     }
    101     pushupx(p);
    102 }
    103 
    104 void updatey(int p , int l , int r , int add) {
    105     int mid = (T2[p].l + T2[p].r) >> 1;
    106     if(T2[p].l == l && T2[p].r == r) {
    107         T2[p].add += add;
    108         pushupy(p);
    109         return ;
    110     }
    111     if(r <= mid) {
    112         updatey(p << 1 , l , r , add);
    113     }
    114     else if(l >= mid) {
    115         updatey((p << 1)|1 , l , r , add);
    116     }
    117     else {
    118         updatey(p << 1 , l , mid , add);
    119         updatey((p << 1)|1 , mid , r , add);
    120     }
    121     pushupy(p);
    122 }
    123 
    124 int main()
    125 {
    126     LL w , h , n , m , x1 , x2 , y1 , y2;
    127     while(~scanf("%lld %lld %lld %lld" , &w , &h , &n , &m)) {
    128         mp1.clear();
    129         mp2.clear();
    130         f1 = f2 = 0;
    131         if(m == 1) {
    132             LL sum = 0;
    133             while(n--) {
    134                 scanf("%lld %lld %lld %lld" , &x1 , &y1 , &x2 , &y2);
    135                 sum += (fab(x1 - x2) + 1) * (fab(y1 - y2) + 1);
    136             }
    137             printf("%lld
    " , h * w - sum);
    138             continue;
    139         }
    140         for(int i = 0 ; i < n ; i++) {
    141             scanf("%lld %lld %lld %lld" , &x1 , &y1 , &x2 , &y2);
    142             x1-- , y1--;
    143             int ls = i << 1 , rs = (i << 1)|1;
    144             line1[ls].l = x1 , line1[ls].r = min(w , x2 + m - 1) , line1[ls].h = y1 , line1[ls].flag = 1;
    145             line1[rs].l = x1 , line1[rs].r = line1[ls].r , line1[rs].h = y2 , line1[rs].flag = -1;
    146             line2[ls].l = y1 , line2[ls].r = min(h , y2 + m - 1) , line2[ls].h = x1 , line2[ls].flag = 1;
    147             line2[rs].l = y1 , line2[rs].r = line2[ls].r , line2[rs].h = x2 , line2[rs].flag = -1;
    148             add1(line1[ls].l);
    149             add1(line1[ls].r);
    150             add1(line1[rs].l);
    151             add1(line1[rs].r);
    152             add2(line2[ls].l);
    153             add2(line2[ls].r);
    154             add2(line2[rs].l);
    155             add2(line2[rs].r);
    156         }
    157         int ls = n << 1 , rs = (n << 1)|1 , f = ((n << 1)|1) + 1;
    158         line1[ls].l = 0 , line1[ls].r = m - 1 , line1[ls].h = 0 , line1[ls].flag = 1;
    159         line1[rs].l = 0 , line1[rs].r = m - 1 , line1[rs].h = h , line1[rs].flag = -1;
    160         line2[ls].l = 0 , line2[ls].r = m - 1 , line2[ls].h = 0 , line2[ls].flag = 1;
    161         line2[rs].l = 0 , line2[rs].r = m - 1 , line2[rs].h = w , line2[rs].flag = -1;
    162         add1(line1[ls].l);
    163         add1(line1[ls].r);
    164         add1(line1[rs].l);
    165         add1(line1[rs].r);
    166         add2(line2[ls].l);
    167         add2(line2[ls].r);
    168         add2(line2[rs].l);
    169         add2(line2[rs].r);
    170         sort(line1 , line1 + f);
    171         sort(line2 , line2 + f);
    172         sort(x + 1 , x + f1 + 1);
    173         sort(y + 1 , y + f2 + 1);
    174         for(int i = 0 ; i < f ; i++) {
    175             line1[i].ll = lower_bound(x + 1 , x + f1 + 1 , line1[i].l) - x;
    176             line1[i].rr = lower_bound(x + 1 , x + f1 + 1 , line1[i].r) - x;
    177             line2[i].ll = lower_bound(y + 1 , y + f2 + 1 , line2[i].l) - y;
    178             line2[i].rr = lower_bound(y + 1 , y + f2 + 1 , line2[i].r) - y;
    179         }
    180         LL res1 = 0 , res2 = 0;
    181         buildx(1 , 1 , f1);
    182         buildy(1 , 1 , f2);
    183         updatex(1 , line1[0].ll , line1[0].rr , line1[0].flag);
    184         updatey(1 , line2[0].ll , line2[0].rr , line2[0].flag);
    185         for(int i = 1 ; i < f ; i++) {
    186             res1 += (line1[i].h - line1[i - 1].h) * T1[1].val;
    187             res2 += (line2[i].h - line2[i - 1].h) * T2[1].val;
    188             updatex(1 , line1[i].ll , line1[i].rr , line1[i].flag);
    189             updatey(1 , line2[i].ll , line2[i].rr , line2[i].flag);
    190         }
    191         printf("%lld
    " , h * w * 2 - res1 - res2);
    192     }
    193 }
  • 相关阅读:
    Linux-配置共享目录
    Linux-expect脚本-编写一个expect脚本
    MySQL-Linux下安装
    ETL-拉链算法-1
    ETL-拉链算法-带删除的拉链算法
    postgresql-基础-1
    Oracle-sql*plus
    【剑指offer11二进制中1的个数】
    【剑指offer10 矩形覆盖】
    【剑指offer080 09 跳台阶、变态跳台阶】
  • 原文地址:https://www.cnblogs.com/Recoder/p/5455413.html
Copyright © 2020-2023  润新知