给出一根木棒长度,没单位一距离为一段,从0开始标号的。。。。
然后给出区间进行黑白染色,查询所给区间内总共有多少根木棒,被颜色隔开的。。
在这里用一个变量保存当前区间的颜色,要求是此区间必须全都是一种颜色,否则col=-1
如果要在这个区间染色的话,那么根节点的col要传递到两个子节点,根节点再赋值为-1,因为此时这个区间不再同色,但是在更新之前两个子区间同色要把状态传递下去 。。
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <stack> #include <climits> #define L(x) (x << 1) #define R(x) (x << 1 | 1) using namespace std; const int MAX = 8010; struct Tnode{ int col; int l,r;}; Tnode node[MAX*3]; int col[MAX],len[MAX];; void init() { memset(node,0,sizeof(node)); memset(col,-1,sizeof(col)); memset(len,0,sizeof(len)); } void build(int t,int l,int r) { node[t].l = l; node[t].r = r; node[t].col = -1; if( l == r - 1 ) return ; int mid = ( l + r ) >> 1; build(L(t), l, mid); build(R(t), mid, r); } void update(int t,int l,int r,int col) { if( node[t].l >= l && node[t].r <= r ) { node[t].col = col; return ; } if( node[t].col == col ) return ;// 如果父亲节点已经是这种颜色了,就没必要再染色了 if( node[t].l == node[t].r - 1 ) return ;//叶子节点没必要更新 if( node[t].col >= 0 )//更新前,区间同色,把颜色状态传递下去 { node[R(t)].col = node[t].col; node[L(t)].col = node[t].col; node[t].col = -1; } int mid = (node[t].l + node[t].r) >> 1; if( l < mid ) update(L(t),l,r,col); if( r > mid ) update(R(t),l,r,col); } void get(int t,int l,int r) { if( node[t].col >= 0 ) { for(int i=l; i<r; i++)//按照所划分的区间,把每一段的颜色球出来 col[i] = node[t].col; return ; } if( node[t].l == node[t].r - 1 ) return ; int mid = (node[t].l + node[t].r) >> 1; if( l >= mid ) get(R(t),l,r); else if( r <= mid ) get(L(t),l,r); else { get(R(t),l,r); get(L(t),l,r); } } int main() { int n,x,y,color; while( ~scanf("%d",&n) ) { init(); build(1,0,MAX); while( n-- ) { scanf("%d%d%d",&x,&y,&color); update(1,x,y,color); } get(1,0,MAX); for(int i=0; i<MAX; i++) if( col[i+1] != col[i] && col[i] != -1 ) len[col[i]]++; for(int i=0; i<MAX; i++) if( len[i] ) printf("%d %d\n",i,len[i]); printf("\n"); } return 0; }