题目:http://poj.org/problem?id=2777
区间更新,比点更新多一点内容, 详见注释, 参考了一下别人的博客。。。。
参考博客:http://www.2cto.com/kf/201402/277917.html
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 using namespace std; 6 const int maxn = 100000 + 10; 7 8 bool mark[35]; 9 struct node 10 { 11 int l, r, kind; 12 }tr[maxn<<2]; 13 14 void build(int t, int l, int r) //建树 15 { 16 tr[t].l = l; 17 tr[t].r = r; 18 tr[t].kind = 1; 19 if(l == r) return; 20 int mid = (l+r)>>1; 21 build(2*t, l, mid); 22 build(2*t+1, mid+1, r); 23 } 24 void update(int t, int l, int r, int cover) //区间颜色更新 25 { 26 if(tr[t].l == l&& tr[t].r == r) //找到区间改颜色 27 { 28 tr[t].kind = cover; 29 return; 30 } 31 if(tr[t].kind != 0&& tr[t].kind != cover) //区间是纯色,而且不是目标颜色 32 { 33 tr[2*t].kind = tr[t].kind; 34 tr[2*t+1].kind = tr[t].kind; //更新子树颜色 35 tr[t].kind = 0; //标记为混合色 36 } 37 int mid = (tr[t].l + tr[t].r)>>1; 38 if(r <= mid) 39 update(2*t, l, r, cover); 40 else if(l > mid) 41 update(2*t+1, l, r, cover); 42 else //左右子树各有一段 43 { 44 update(2*t, l, mid, cover); 45 update(2*t+1, mid+1, r, cover); 46 } 47 } 48 void query(int t, int l, int r) 49 { 50 if(tr[t].kind > 0) //该段为纯色,不用向下搜了 51 { 52 mark[tr[t].kind] = true; 53 return; 54 } 55 int mid = (tr[t].l + tr[t].r)>>1; 56 if(r <= mid) 57 query(2*t, l, r); 58 else if(l > mid) 59 query(2*t+1, l, r); 60 else 61 { 62 query(2*t, l, mid); 63 query(2*t+1, mid+1, r); 64 } 65 } 66 int main() 67 { 68 int n, color, m, i; 69 int a, b, c, sum; 70 char ch[10]; 71 scanf("%d%d%d", &n, &color, &m); 72 build(1, 1, n); 73 while(m--) 74 { 75 scanf("%s",ch); 76 if(ch[0] == 'C') 77 { 78 scanf("%d%d%d", &a, &b, &c); 79 if(a > b) 80 update(1, b, a, c); 81 else 82 update(1, a, b, c); 83 } 84 else 85 { 86 scanf("%d%d", &a, &b); 87 memset(mark, false, sizeof(mark)); 88 if(a > b) 89 query(1, b, a); 90 else 91 query(1, a, b); 92 sum = 0; 93 for(i = 1; i <= color; i++) 94 { 95 if(mark[i]) 96 { 97 sum += 1; 98 //cout<<i<<endl; 99 } 100 } 101 printf("%d ", sum); 102 } 103 } 104 return 0; 105 }