日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

hdu 4419 Colourful Rectangle (离散化扫描线线段树)

發(fā)布時(shí)間:2024/4/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu 4419 Colourful Rectangle (离散化扫描线线段树) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Problem - 4419

  題意不難,紅綠藍(lán)三種顏色覆蓋在平面上,不同顏色的區(qū)域相交會(huì)產(chǎn)生新的顏色,求每一種顏色的面積大小。

  比較明顯,這題要從矩形面積并的方向出發(fā)。如果做過(guò)矩形面積并的題,用線段樹做的,這題就只差一個(gè)把每個(gè)區(qū)域計(jì)算單獨(dú)出來(lái)的思路了。

  這里不詳細(xì)介紹掃描線,只是說(shuō)一下針對(duì)這題的做法。其實(shí)網(wǎng)上有好多版本,都是直接單獨(dú)計(jì)算答案的。然而,我稍微繞了個(gè)小彎,我覺(jué)得我這種處理方法也是比較容易想到以及實(shí)現(xiàn)的。如果我們用7棵線段樹計(jì)算R、G、B、R||G、R||B、B||G、R||G||B這7種情況,我們并不能直接得到所要的答案。不過(guò)可以知道,ans(G)=S(R||G||B)-S(R||B)的(這里的||是兩種顏色的面積并的意思)。同理我們可以得到ans(B)、ans(R)。然后根據(jù)這個(gè),我們可以得到ans(RB)=S(R||G||B)-ans(R)-ans(B)-S(G)。同理可以得到ans(RG),ans(GB)。最后就只剩ans(RGB)了。

代碼如下:

1 #include <cstdio> 2 #include <cstring> 3 #include <map> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 map<char, int> id; 10 void preMap() { 11 id['R'] = 0; 12 id['G'] = 1; 13 id['B'] = 2; 14 } 15 16 const int N = 22222; 17 const int K = 1 << 3; 18 map<int, int> xid; 19 int rx[N], xn; 20 21 struct Node { 22 int id, x1, x2, y; 23 bool end; 24 Node() {} 25 Node(int id, int x1, int x2, int y, bool end) 26 : id(id), x1(x1), x2(x2), y(y), end(end) {} 27 } node[N]; 28 29 void input(int n) { 30 char buf[3]; 31 int a, b, c, d; 32 for (int i = 0; i < n; i++) { 33 scanf("%s%d%d%d%d", buf, &a, &b, &c, &d); 34 if (a > c) swap(a, c); 35 if (b > d) swap(b, d); 36 rx[i << 1] = a; 37 rx[i << 1 | 1] = c; 38 node[i << 1] = Node(id[buf[0]], a, c, b, false); 39 node[i << 1 | 1] = Node(id[buf[0]], a, c, d, true); 40 } 41 n <<= 1; 42 sort(rx, rx + n); 43 xn = unique(rx, rx + n) - rx; 44 // for (int i = 0; i < xn; i++) cout << rx[i] << ' '; cout << endl; 45 xid.clear(); 46 for (int i = 0; i < xn; i++) xid[rx[i]] = i; 47 for (int i = 0; i < n; i++) { 48 node[i].x1 = xid[node[i].x1]; 49 node[i].x2 = xid[node[i].x2]; 50 } 51 } 52 53 #define lson l, m, rt << 1 54 #define rson m + 1, r, rt << 1 | 1 55 #define root 0, xn - 1, 1 56 57 int sum[K][N << 2]; 58 int mk[K][N << 2]; 59 int cur; 60 61 void up(int rt, int l, int r) { 62 if (mk[cur][rt]) sum[cur][rt] = rx[r + 1] - rx[l]; 63 else sum[cur][rt] = sum[cur][rt << 1] + sum[cur][rt << 1 | 1]; 64 } 65 66 void build(int l, int r, int rt) { 67 sum[cur][rt] = mk[cur][rt] = 0; 68 if (l == r) return ; 69 int m = l + r >> 1; 70 build(lson); 71 build(rson); 72 } 73 74 void update(int k, int L, int R, int l, int r, int rt) { 75 if (L <= l && r <= R) { 76 mk[cur][rt] += k; 77 if (l != r) up(rt, l, r); 78 else { 79 if (mk[cur][rt]) sum[cur][rt] = rx[r + 1] - rx[l]; 80 else sum[cur][rt] = 0; 81 } 82 return ; 83 } 84 int m = l + r >> 1; 85 if (L <= m) update(k, L, R, lson); 86 if (m < R) update(k, L, R, rson); 87 up(rt, l, r); 88 } 89 90 bool cmp(Node a, Node b) { return a.y < b.y || a.y == b.y && a.end < b.end;} 91 92 typedef long long LL; 93 94 void work(int n) { 95 n <<= 1; 96 LL tt[K]; 97 memset(tt, 0, sizeof(tt)); 98 sort(node, node + n, cmp); 99 if (node[0].end) { puts("shit!!"); while (1) ;} 100 for (cur = 0; cur < K; cur++) { 101 build(root); 102 if (cur & 1 << node[0].id) update(1, node[0].x1, node[0].x2 - 1, root); 103 } 104 for (int i = 1; i < n; i++) { 105 for (cur = 0; cur < K; cur++) { 106 if (sum[cur][1] < 0 || sum[cur][1] > 1e9) { puts("shit!!!"); while (1) ;} 107 tt[cur] += (LL) sum[cur][1] * (node[i].y - node[i - 1].y); 108 if (cur & (1 << node[i].id)) update(node[i].end ? -1 : 1, node[i].x1, node[i].x2 - 1, root); 109 } 110 // for (int i = 0; i < K; i++) cout << tt[i] << ' '; cout << endl; 111 } 112 LL sgl[3], dbl[3], lst = tt[K - 1]; 113 for (int i = 0; i < 3; i++) { 114 sgl[i] = tt[K - 1] - tt[(K - 1) ^ (1 << i)]; 115 lst -= sgl[i]; 116 cout << sgl[i] << endl; 117 } 118 for (int i = 0; i < 3; i++) { 119 dbl[i] = tt[K - 1]; 120 for (int j = 0; j < 3; j++) { 121 if (i != j) dbl[i] -= sgl[j]; 122 else dbl[i] -= tt[1 << j]; 123 } 124 lst -= dbl[i]; 125 } 126 for (int i = 2; i >= 0; i--) cout << dbl[i] << endl; 127 cout << lst << endl; 128 } 129 130 int main() { 131 // freopen("in", "r", stdin); 132 preMap(); 133 int T, n; 134 scanf("%d", &T); 135 for (int cas = 1; cas <= T; cas++) { 136 scanf("%d", &n); 137 input(n); 138 printf("Case %d:\n", cas); 139 work(n); 140 } 141 return 0; 142 } View Code

  感覺(jué)這種方法寫起來(lái)不會(huì)吃力,就是計(jì)算上面會(huì)稍微需要思考。不過(guò)我還是因?yàn)榘褁id寫成xd導(dǎo)致wa了一個(gè)晚上。_(囧」∠)_

?

——written by Lyon

?

轉(zhuǎn)載于:https://www.cnblogs.com/LyonLys/p/hdu_4419_Lyon.html

總結(jié)

以上是生活随笔為你收集整理的hdu 4419 Colourful Rectangle (离散化扫描线线段树)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。