1 /*hdu 4391 Paint The Wall 区间修改加最大最小值优化 2 *@题意 :: 刷墙,以开始有n个节点,每个节点有一种颜色,m次询问输入a,l,r,z。 3 * 如果 a=1 将l到r刷为z颜色。 4 * 如果 a=2 询问l到r有多少个和z相同的节点 5 */ 6 #include<stdio.h> 7 const int N = 100010; 8 struct Line { 9 int col; 10 int min, max; 11 }T[N * 4]; 12 void Push_up(int o) { 13 int lc = o * 2, rc = o * 2 + 1; 14 if(T[o].col == -1 && T[lc].col == T[rc].col) T[o].col = T[lc].col; 15 T[o].min = T[lc].min < T[rc].min ? T[lc].min : T[rc].min; 16 T[o].max = T[lc].max > T[rc].max ? T[lc].max : T[rc].max; 17 } 18 void Push_down(int o) { 19 int lc = o * 2, rc = o * 2 + 1; 20 if(T[o].col != -1) { 21 T[lc].col = T[rc].col = T[o].col; 22 T[o].col = -1; 23 T[lc].min = T[rc].min = T[o].min; 24 T[lc].max = T[rc].max = T[o].max; 25 } 26 } 27 int v[N]; 28 void build(int o, int L, int R) { 29 T[o].col = -1; 30 if(L == R) { 31 T[o].min = T[o].max = T[o].col = v[L]; 32 return; 33 } 34 int M = (L + R) / 2; 35 build(o * 2, L, M); 36 build(o * 2 + 1, M + 1, R); 37 Push_up(o); 38 } 39 int y1, y2; 40 void updata(int o, int L, int R, int col) { 41 int lc = o * 2, rc = o * 2 + 1; 42 if(y1 <= L && y2 >= R) { 43 T[o].max = T[o].min = T[o].col = col; 44 return; 45 } 46 Push_down(o); 47 int M = (L + R) / 2; 48 if(y1 <= M) updata(lc, L, M, col); 49 if(y2 > M) updata(rc, M + 1, R, col); 50 Push_up(o); 51 } 52 int ans; 53 void query(int o, int L ,int R, int col) { 54 if(col < T[o].min || col > T[o].max) return; 55 if(T[o].col != -1 && T[o].col == col) { 56 int rr = R < y2 ? R : y2; 57 int ll = L > y1 ? L : y1; 58 ans += rr - ll + 1; 59 return; 60 } 61 int M = (L + R) / 2; 62 if(y1 <= M) query(o * 2, L, M, col); 63 if(y2 > M) query(o * 2 + 1, M + 1, R, col); 64 } 65 int main() { 66 int n, m; 67 while(scanf("%d%d", &n, &m) != EOF) { 68 for(int i = 1; i <= n; ++i) scanf("%d", &v[i]); 69 build(1, 1, n); 70 while(m--) { 71 int a, z; 72 scanf("%d%d%d%d", &a, &y1, &y2, &z); 73 y1++; y2++; 74 if(a == 1) updata(1, 1, n, z); 75 else { 76 ans = 0; 77 query(1, 1, n, z); 78 printf("%d\n", ans); 79 } 80 } 81 } 82 return 0; 83 }