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\n" , 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\n" , h * w * 2 - res1 - res2); 192 } 193 }