用线段树进行区间赋值,最后将每个小segment的颜色求出来,再扫一遍判断连续的段数即可。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 8001; 7 int color[N]; 8 int ans[N]; 9 10 struct Node 11 { 12 int l, r, c; 13 } node[N << 2]; 14 15 void build( int i, int l, int r ) 16 { 17 node[i].l = l, node[i].r = r, node[i].c = -1; 18 if ( l == r ) return ; 19 int mid = ( l + r ) >> 1; 20 build( i << 1, l, mid ); 21 build( i << 1 | 1, mid + 1, r ); 22 } 23 24 void pushdown( int i ) 25 { 26 if ( node[i].c != -1 ) 27 { 28 node[i << 1].c = node[i << 1 | 1].c = node[i].c; 29 node[i].c = -1; 30 } 31 } 32 33 void update( int i, int l, int r, int c ) 34 { 35 if ( node[i].l == l && node[i].r == r ) 36 { 37 node[i].c = c; 38 return ; 39 } 40 pushdown(i); 41 int mid = ( node[i].l + node[i].r ) >> 1; 42 if ( r <= mid ) 43 { 44 update( i << 1, l, r, c ); 45 } 46 else if ( l > mid ) 47 { 48 update( i << 1 | 1, l, r, c ); 49 } 50 else 51 { 52 update( i << 1, l, mid, c ); 53 update( i << 1 | 1, mid + 1, r, c ); 54 } 55 } 56 57 void pushalldown( int i ) 58 { 59 if ( node[i].l == node[i].r ) 60 { 61 if ( node[i].c != -1 ) 62 { 63 color[node[i].l] = node[i].c; 64 } 65 return ; 66 } 67 pushdown(i); 68 pushalldown( i << 1 ); 69 pushalldown( i << 1 | 1 ); 70 } 71 72 int main () 73 { 74 int n; 75 while ( scanf("%d", &n) != EOF ) 76 { 77 build( 1, 1, 8000 ); 78 for ( int i = 1; i <= n; i++ ) 79 { 80 int x, y, z; 81 scanf("%d%d%d", &x, &y, &z); 82 update( 1, x + 1, y, z ); 83 } 84 memset( color, -1, sizeof(color) ); 85 pushalldown(1); 86 memset( ans, 0, sizeof(ans) ); 87 for ( int i = 1; i <= 8000; i++ ) 88 { 89 if ( color[i] == -1 ) continue; 90 ans[color[i]]++; 91 while ( i + 1 <= 8000 && color[i] == color[i + 1] ) 92 { 93 i++; 94 } 95 } 96 for ( int i = 0; i <= 8000; i++ ) 97 { 98 if ( ans[i] ) 99 { 100 printf("%d %d\n", i, ans[i]); 101 } 102 } 103 putchar(‘\n‘); 104 } 105 return 0; 106 }
时间: 2024-10-18 10:04:25