POJ-2528 modified segment tree section

First, the content

Here Insert Picture DescriptionHere Insert Picture Description

Second, the idea

  • Is seeking a total of how many posters they can see, attach a color to each poster, and finally find yourself able to see how many colors.

  • Discrete data, because it is continuous for a period of, so that when the difference between the two points is greater than 1, it should add a point in the middle.
    Such as [1, 1,4] [10] [5, 10] is discretization [1,4] [1,2] [3, 4]
    However, [1, 10] [6] [1, 4, 10 discretization] [1,4] is [1,2] [3, 4], however, the number should be seen in this case 3
    so we should add a point intermediate 5 in 4 and 6, carried out by a modified section when you can not go wrong.

  • Color [] The initial value of -1 indicates no color or a variety of colors, with each time we are updated to the new time period on the line section, and each time pushdown (); the interval period interval divided into two stages, due to the coverage interval may be a period of sub-intervals.
    - The last query () how many colors there are a query on the list, with a vis record color've seen .

Third, the code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> 
using namespace std;
const int maxn = 2e4 + 5;


//color用来保存一段区间的颜色,vis用来统计颜色  lId保存海报的左端点    id保存离散化后的编号 
int color[maxn << 4], vis[maxn << 4], lId[maxn], rId[maxn], id[maxn << 2];  
int t, n, cnt, ans; 
void pushdown(int id) {
	if (color[id] == -1) return;
	//对修改过的区间进行下放 
	color[id << 1] = color[id << 1 | 1] = color[id];
	color[id]  = -1;
}

void update(int id, int l, int r, int x, int y, int v) {
	if (x <= l && r <= y) {
		//对区间进行修改 
		color[id] = v;
		return;
	}
	 pushdown(id);
	int mid = (l + r) >> 1;
	if (x <= mid) {
		update(id << 1, l , mid, x, y, v); 
	}		 
	if (y > mid) {
		update(id << 1 | 1, mid + 1, r, x, y, v);
	}
	//这种还不用pushup 
} 
void  query(int id, int l, int r) {
	if (color[id] != -1) {
		//记录一种color 
		if (!vis[color[id]]) {
			ans++;
			vis[color[id]] = 1;
		}
		return;
	}
	if (l == r) return; 
	int mid = (l + r) >> 1;
	query(id << 1, l, mid);
	query(id << 1 | 1, mid + 1,r);
}


int main() {
	scanf("%d", &t);
	while (t--) {
		cnt = 0;
		ans = 0;
		memset(color, -1, sizeof(color));
		memset(vis, 0, sizeof(vis));
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			scanf("%d%d", lId + i, rId + i);
			id[++cnt] = lId[i];
			id[++cnt] = rId[i];
		} 
		sort(id + 1, id + cnt + 1);
		int t = unique(id + 1, id + cnt + 1) - id - 1;
		int m = t;
		for (int i = 2; i <= t; i++) {
			if (id[i] - id[i - 1] > 1) {
				//成段的离散化若差值大于1 中间还应该添加一个点 
				id[++m] = id[i  - 1] + 1;
			}
		}
		cnt = m;
		sort(id + 1, id + cnt + 1);
		for (int i = 1; i <= n; i++) {
			int x = lower_bound(id + 1, id + cnt + 1, lId[i]) - id;
			int y = lower_bound(id + 1, id + cnt + 1, rId[i]) - id;
			update(1, 1, cnt, x, y, i);
		}
		query(1, 1, cnt); 
		printf("%d\n", ans);
	}
	
	
	return 0;
} 
Published 343 original articles · won praise 244 · views 40000 +

Guess you like

Origin blog.csdn.net/qq_41280600/article/details/100801261