zoj1016

线段树真的很灵活很巧妙。

像这道题,更新完之后,只要查询每个位置是什么颜色, 它和前一个位置的关系就可以了,想不到想不到

#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson(x) ((x) << 1)
#define rson(x) ((x) << 1 | 1)
using namespace std;

const int N = 8080;

int lc[N << 2], rc[N << 2], s[N << 2];

inline void pushdown(int node){
	if(s[node] != -1){
		s[lson(node)] = s[rson(node)] = s[node];
		s[node] = -1;
	}
}
void build(int node, int l, int r){
	lc[node] = l;
	rc[node] = r;
	s[node] = -1;
	if(l == r)
		return ;
	int mid = (l + r) >> 1;
	build(lson(node), l, mid);
	build(rson(node), mid + 1, r);
}
void update(int node, int l, int r, int w){
	if(l <= lc[node] && rc[node] <= r){
		s[node] = w;
		return ;
	}
	pushdown(node);
	int mid = (lc[node] + rc[node]) >> 1;
	if(l <= mid)
		update(lson(node), l, r, w);
	if(r > mid)
		update(rson(node), l, r, w);
}
int query(int node, int x){
	if(lc[node] == x && x == rc[node])
		return s[node];
	pushdown(node);
	int mid = (lc[node] + rc[node]) >> 1;
	if(x <= mid)
		return query(lson(node), x);
	else
		return query(rson(node), x);
}

int n, ans[N];

int main(){
	int l, r, c;
	while(~ scanf("%d", &n)){
		build(1, 0, 8000);
		for(int i = 0; i < n; i ++){
			scanf("%d %d %d", &l, &r, &c);
			update(1, l, r - 1, c);
		}
		int pre = -1;
		memset(ans, 0, sizeof(ans));
		for(int i = 0; i <= 8000; i ++){
			int k = query(1, i);
			if(k != pre && k != -1)
				ans[k] ++;
			pre = k;
		}
		for(int i = 0; i <= 8000; i ++){
			if(ans[i])
				printf("%d %d\n", i, ans[i]);
		}
		printf("\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/82502377