线段树真的很灵活很巧妙。
像这道题,更新完之后,只要查询每个位置是什么颜色, 它和前一个位置的关系就可以了,想不到想不到
#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;
}