程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1436 Horizontally Visible Segments(線段樹)

POJ 1436 Horizontally Visible Segments(線段樹)

編輯:C++入門知識

POJ 1436 Horizontally Visible Segments(線段樹)


POJ 1436 Horizontally Visible Segments

題目鏈接

線段樹處理染色問題,把線段排序,從左往右掃描處理出每個線段能看到的右邊的線段,然後利用bitset維護枚舉兩個線段,找出另一個兩個都有的線段

代碼:

#include 
#include 
#include 
#include 
#include 
using namespace std;

const int N = 8005;
bitset g[N];
int t, n;

struct Seg {
	int x, y1, y2;
	void read() {
		scanf("%d%d%d", &y1, &y2, &x);
	}
} s[N];

bool cmp(Seg a, Seg b) {
	return a.x < b.x;
}

#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)

struct Node {
	int l, r, val, setv;
} node[N * 4 * 2];

void pushup(int x) {
	if (node[lson(x)].val == node[rson(x)].val) node[x].val = node[lson(x)].val;
	else node[x].val = -1;
}

void pushdown(int x) {
	if (node[x].setv != -1) {
		node[lson(x)].val = node[rson(x)].val = node[x].setv;
		node[lson(x)].setv = node[rson(x)].setv = node[x].setv;
		node[x].setv = -1;
	}
}

void build(int l, int r, int x = 0) {
	node[x].l = l; node[x].r = r; node[x].val = -1; node[x].setv = -1;
	if (l == r)
		return;
	int mid = (l + r) / 2;
	build(l, mid, lson(x));
	build(mid + 1, r, rson(x));
}

vector g2[N];

void add(int l, int r, int v, int x = 0) {
	if (node[x].val != -1 && node[x].l >= l && node[x].r <= r) {
		if (g[node[x].val][v] == false)
			g2[node[x].val].push_back(v);
		g[node[x].val][v] = true;
		node[x].setv = v;
		node[x].val = v;
		return;
	}
	if (node[x].l == node[x].r) {
		node[x].val = v;
		return;
	}
	pushdown(x);
	int mid = (node[x].l + node[x].r) / 2;
	if (l <= mid) add(l, r, v, lson(x));
	if (r > mid) add(l, r, v, rson(x));
	pushup(x);
}

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			g[i].reset();
			g2[i].clear();
			s[i].read();
		}
		sort(s, s + n, cmp);
		build(0, N * 2 - 1);
		for (int i = 0; i < n; i++)
			add(s[i].y1 * 2, s[i].y2 * 2, i);
		int ans = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < g2[i].size(); j++) {
				if (g[i][g2[i][j]])
					ans += (g[i]&g[g2[i][j]]).count();
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved