zoj 1610 Count the Colors

来源:互联网 发布:mac地址转换 编辑:程序博客网 时间:2024/05/05 04:15

线段树水题。

注意更新子节点,如果遇到的父节点已经被颜色覆盖掉的话,父节点 的颜色需要往下传递(因为父节点已经不会是原来那种颜色了)。

#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));}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 Updata(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].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 )Updata(R(t),l,r,col);elseif( r <= mid )Updata(L(t),l,r,col);else{Updata(L(t),l,mid,col);Updata(R(t),mid,r,col);}}void Compute(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 )Compute(R(t),l,r);elseif( r <= mid )Compute(L(t),l,r);else{Compute(L(t),l,mid);Compute(R(t),mid,r);}}int main(){int n,x,y,color;while( ~scanf("%d",&n) ){init();Build(1,0,8000);while( n-- ){scanf("%d%d%d",&x,&y,&color);Updata(1,x,y,color);}Compute(1,0,8000);memset(len,0,sizeof(len));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;}


原创粉丝点击