http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=216#problem/U
有n个操作,每个操作定义为x1,x2,c,表示把区间[x1,x2]染成c色,区间可重复染色,最后问每种颜色存在几个间断的区间中。
注意是对区间进行染色,而不是点。
成段更新很简单,在统计每种颜色所在间断的区间时,先把线段树中节点信息映射到数组中然后统计,没想到这一点,一直在想怎么在线段树上进行统计。
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) using namespace std; const int maxn = 8010; struct node { int l,r; int col; }tree[maxn*4]; int ans[maxn]; int arr[maxn]; void build(int v, int l, int r) { tree[v].l = l; tree[v].r = r; tree[v].col = -1; if(l == r) return; int mid = (l + r) >> 1; build(v*2,l,mid); build(v*2+1,mid+1,r); } void update(int v, int l, int r, int col) { if(tree[v].l == l && tree[v].r == r) { tree[v].col = col; return; } if(tree[v].col != -1) { tree[v*2].col = tree[v*2+1].col = tree[v].col; tree[v].col = -1; } int mid = (tree[v].l + tree[v].r) >> 1; if(r <= mid) update(v*2,l,r,col); else if(l > mid) update(v*2+1,l,r,col); else { update(v*2,l,mid,col); update(v*2+1,mid+1,r,col); } } void query(int v, int l, int r) { if(tree[v].col != -1) { for(int i = tree[v].l; i <= tree[v].r; i++) { arr[i] = tree[v].col; } return; } if(tree[v].l == tree[v].r) { arr[tree[v].l] = tree[v].col; return; } int mid = (tree[v].l + tree[v].r) >> 1; if(r <= mid) query(v*2,l,r); else if(l > mid) query(v*2+1,l,r); else { query(v*2,l,mid); query(v*2+1,mid+1,r); } } int main() { int n,cn,t; int ll[maxn],rr[maxn],cc[maxn]; while(~scanf("%d",&t)) { memset(ans,0,sizeof(ans)); n = -1; cn = -1; for(int i = 1; i <= t; i++) { scanf("%d %d %d",&ll[i],&rr[i],&cc[i]); n = max(n,rr[i]); cn = max(cn,cc[i]); } build(1,0,n-1); for(int i = 1; i <= t; i++) { update(1,ll[i],rr[i]-1,cc[i]); } query(1,0,n-1); ans[arr[0]] += 1; for(int i = 1; i <= n-1; i++) { if(arr[i] != arr[i-1]) ans[arr[i]] += 1; } for(int i = 0; i <= cn; i++) { if(ans[i]) printf("%d %d\n",i,ans[i]); } printf("\n"); } return 0; }