zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    OPPO R9sPlus MIFlash线刷TWRP Recovery ROOT详细教程
    OPPO R11 R11plus系列 解锁BootLoader ROOT Xposed 你的手机你做主
    努比亚(nubia) M2青春版 NX573J 解锁BootLoader 并进入临时recovery ROOT
    华为 荣耀 等手机解锁BootLoader
    青橙 M4 解锁BootLoader 并刷入recovery ROOT
    程序员修炼之道阅读笔03
    冲刺8
    典型用户模板分析
    学习进度八
    冲刺7
  • 原文地址:https://www.cnblogs.com/Recoder/p/5455413.html
Copyright © 2011-2022 走看看