數算實習 Mayor's posters 線段樹 離散化
阿新 • • 發佈:2019-02-16
Mayor’s posters每個候選人都可以在牆上放置一張海報。
所有海報的高度都與牆的高度相同; 海報的寬度可以是任何整數個單位。
牆被分成10000000段,每段的寬度是一個單位。每張海報必須完全覆蓋連續數量個單位的牆壁。
你的任務是找到所有海報放置完畢後可見海報的數量。
輸入:
第一行輸入包含一個數字c,給出了後面的案例數。單個案例的第一行資料包含數字1 <= n <= 10000。隨後的n行按照海報的放置順序給出海報的左端編號和右端編號。
輸出:
海報貼上完畢後能看到的海報數量
樣例輸入
1
5
1 4
2 6
8 10
3 4
7 10
樣例輸出
4
#include <iostream> #include <algorithm> using namespace std; int sum; int flag; struct post { int l; int r; }; struct cnode { int l; int r; bool covered; cnode *left; cnode *right; }; struct section { int l; int r; }; void buildtree(cnode* root, section* s, int le, int ri) { root->covered = 0; if (le == ri) return; root->left = new cnode; root->right = new cnode; int mid = (le + ri) / 2; root->left->l = s[le].l; root->left->r = s[mid].r; root->right->l = s[mid + 1].l; root->right->r = s[ri].r; buildtree(root->left, s, le, mid); buildtree(root->right, s, mid + 1, ri); } void quary(cnode* root, int L, int R) { if (root->l == L && root->r == R) { if (root->covered == 1) return; else { root->covered = 1; flag = 1; return; } } else { if (root->covered == 1) return; if (R <= (root->left->r)) { quary(root->left, L, R); } else if (L >= (root->right->l)) { quary(root->right, L, R); } else { quary(root->left, L, root->left->r); quary(root->right, root->right->l, R); } if (root->left->covered == 1 && root->right->covered == 1) root->covered = 1; } } int main() { int t; cin >> t; while (t--) { post p[10002]; //記錄海報資訊 int point[50004]; //記錄端點值 section s[50004]; //記錄單位區間 sum = 0; int n; cin >> n; int j = 0; for (int i = 1; i <= n; ++i) { cin >> p[i].l >> p[i].r; point[j++] = p[i].l; point[j++] = p[i].r; } sort(point, point + j); int len = 1; for (int k = 0; k < j - 1; k++) //離散化 { if (point[k] != point[k + 1]) { if (point[k + 1] - 1 == point[k]) { s[len].l = point[k]; s[len].r = point[k]; len++; } else { s[len].l = point[k]; s[len].r = point[k]; len++; s[len].l = point[k] + 1; s[len].r = point[k + 1] - 1; len++; } } } s[len].l = point[j - 1]; s[len].r = point[j - 1]; cnode* root = new cnode; root->l = s[1].l; root->r = s[len].r; buildtree(root, s, 1, len); for (int i = n; i >= 1; --i) { flag = 0; int L = p[i].l; int R = p[i].r; quary(root, L, R); sum += flag; } cout << sum << endl; } return 0; }