线段树
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 6 #define lson l, m, rt << 1 7 #define rson m + 1, r, rt << 1 | 1 8 9 using namespace std; 10 11 const int MAXN = 100010; 12 13 int N, Q; 14 int color[ MAXN << 2 ]; //记录该区间的颜色 15 int flag[ MAXN << 2 ]; //记录该区间是否是相同颜色 16 int maxi[ MAXN << 2 ]; //记录区间最值,用于优化查询 17 int mini[ MAXN << 2 ]; 18 19 void PushUp( int rt ) 20 { 21 int lc = rt << 1; 22 int rc = rt << 1 | 1; 23 24 if ( flag[lc] && flag[rc] && color[lc] == color[rc] ) 25 { 26 flag[rt] = 1; 27 color[rt] = color[lc]; 28 } 29 else 30 { 31 flag[rt] = 0; 32 color[rt] = -1; 33 } 34 35 maxi[rt] = max( maxi[lc], maxi[rc] ); 36 mini[rt] = min( mini[lc], mini[rc] ); 37 return; 38 } 39 40 void PushDown( int rt ) 41 { 42 int lc = rt << 1; 43 int rc = rt << 1 | 1; 44 if ( flag[rt] ) 45 { 46 flag[lc] = flag[rc] = flag[rt]; 47 color[lc] = color[rc] = color[rt]; 48 maxi[lc] = maxi[rc] = color[rt]; 49 mini[lc] = mini[rc] = color[rt]; 50 flag[rt] = 0; 51 } 52 return; 53 } 54 55 void build( int l, int r, int rt ) 56 { 57 flag[rt] = 0; 58 if ( l == r ) 59 { 60 scanf( "%d", &color[rt] ); 61 flag[rt] = 1; 62 maxi[rt] = mini[rt] = color[rt]; 63 return; 64 } 65 int m = ( l + r ) >> 1; 66 build( lson ); 67 build( rson ); 68 PushUp( rt ); 69 return; 70 } 71 72 void Update( int L, int R, int z, int l, int r, int rt ) 73 { 74 if ( L <= l && r <= R ) 75 { 76 flag[rt] = 1; 77 color[rt] = z; 78 maxi[rt] = z; 79 mini[rt] = z; 80 return; 81 } 82 PushDown( rt ); 83 84 int m = ( l + r ) >> 1; 85 if ( L <= m ) Update( L, R, z, lson ); 86 if ( R > m ) Update( L, R, z, rson ); 87 88 PushUp(rt); 89 90 return; 91 } 92 93 int Query( int L, int R, int z, int l, int r, int rt ) 94 { 95 if ( L <= l && r <= R ) 96 { 97 if ( flag[rt] && color[rt] == z ) return r - l + 1; 98 else if ( z < mini[rt] || z > maxi[rt] ) return 0; 99 } 100 PushDown(rt); 101 102 int m = ( l + r ) >> 1; 103 int ans = 0; 104 if ( L <= m ) ans += Query( L, R, z, lson ); 105 if ( R > m ) ans += Query( L, R, z, rson ); 106 107 PushUp(rt); 108 return ans; 109 } 110 111 int main() 112 { 113 while ( ~scanf( "%d%d", &N, &Q ) ) 114 { 115 build( 0, N - 1, 1 ); 116 while ( Q-- ) 117 { 118 int a, l, r, z; 119 scanf( "%d%d%d%d", &a, &l, &r, &z ); 120 if ( a == 1 ) Update( l, r, z, 0, N - 1, 1 ); 121 else printf("%d\n", Query( l, r, z, 0, N - 1, 1 ) ); 122 } 123 } 124 return 0; 125 }