Link: http://acm.hdu.edu.cn/showproblem.php?pid=5023
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <string> 7 #include <cmath> 8 using namespace std; 9 typedef __int64 LL; 10 typedef unsigned int UINT; 11 const int maxn = 1e6 + 5; 12 13 #define LEFT(a,b) ((a) << (b)) 14 #define RIGHT(a,b) ((a) >> (b)) 15 16 struct node 17 { 18 UINT c,num; 19 int l,r; 20 node() {} 21 node(const int t_l,const int t_r,const UINT t_c,const UINT t_num) 22 { 23 l = t_l,r = t_r; 24 c = (1 << (t_c - 1)); 25 num = t_num; 26 } 27 }tree[4*maxn]; 28 29 void Init(const int p) 30 { 31 if(tree[p].l == tree[p].r) return ; 32 int mid = RIGHT(tree[p].l + tree[p].r,1); 33 tree[LEFT(p,1)] = node(tree[p].l,mid,2,1); 34 tree[LEFT(p,1)+1] = node(mid+1,tree[p].r,2,1); 35 Init(LEFT(p,1)); 36 Init(LEFT(p,1)+1); 37 } 38 void paste(const int p,const int t_l,const int t_r,const UINT t_c) 39 { 40 if(t_l > t_r) return ; 41 if(t_l == tree[p].l && t_r == tree[p].r) 42 { 43 tree[p].c = t_c; 44 tree[p].num = 1; 45 return ; 46 } 47 int mid = (tree[p].l + tree[p].r) / 2; 48 /* 49 如果该段区间只有一种颜色,则要先把该段区间里的目标区间意外的区间涂成原来的颜色 50 */ 51 if(1 == tree[p].num) 52 { 53 paste(LEFT(p,1),tree[p].l,mid,tree[p].c); 54 paste(LEFT(p,1)+1,mid+1,tree[p].r,tree[p].c); 55 /* 56 if(t_r <= mid) paste(LEFT(p,1)+1,mid+1,tree[p].r,tree[p].c); 57 else if(t_l <= mid && t_r > mid) 58 { 59 paste(LEFT(p,1),tree[p].l,t_l-1,tree[p].c); 60 paste(LEFT(p,1)+1,t_r+1,tree[p].r,tree[p].c); 61 } 62 else if(t_l > mid) paste(LEFT(p,1),tree[p].l,mid,tree[p].c); 63 */ 64 } 65 if(t_r <= mid) paste(LEFT(p,1),t_l,t_r,t_c); 66 else if(t_l <= mid && t_r > mid) 67 { 68 paste(LEFT(p,1),t_l,mid,t_c); 69 paste(LEFT(p,1)+1,mid+1,t_r,t_c); 70 } 71 else if(t_l > mid) paste(LEFT(p,1)+1,t_l,t_r,t_c); 72 73 tree[p].c = tree[LEFT(p,1)].c | tree[LEFT(p,1)+1].c; 74 tree[p].num = 0; 75 for(int i = 0;i <= 29;i++) 76 if(tree[p].c & (1 << i)) 77 tree[p].num++; 78 } 79 80 void quire(const int p,const int t_l,const int t_r,UINT& t_c) 81 { 82 if(1 == tree[p].num || (tree[p].l == t_l && tree[p].r == t_r)) 83 { 84 t_c |= tree[p].c; 85 return ; 86 } 87 int mid = (tree[p].l + tree[p].r) / 2; 88 if(t_r <= mid) quire(LEFT(p,1),t_l,t_r,t_c); 89 else if(t_l <= mid && t_r > mid) 90 { 91 quire(LEFT(p,1),t_l,mid,t_c); 92 quire(LEFT(p,1)+1,mid+1,t_r,t_c); 93 } 94 else if(t_l > mid) quire(LEFT(p,1)+1,t_l,t_r,t_c); 95 } 96 void print() 97 { 98 for(int i = 1;i <= 9;++i) 99 printf("%d ",tree[i].c); 100 puts(""); 101 for(int i = 1;i <= 9;i++) 102 printf("%d ",tree[i].num); 103 puts(""); 104 } 105 int main() 106 { 107 // freopen("in.txt","r",stdin); 108 int n,m; 109 while(scanf("%d%d",&n,&m),m+n) 110 { 111 tree[1] = node(1,n,2,1); 112 Init(1); 113 char oper[3]; 114 while(m--) 115 { 116 scanf("%s",oper); 117 if('P' == oper[0]) 118 { 119 int x,y,c; 120 scanf("%d%d%d",&x,&y,&c); 121 paste(1,x,y,1 << (c - 1)); 122 // print(); 123 } 124 else 125 { 126 int x,y; 127 UINT t_c = 0; 128 scanf("%d%d",&x,&y); 129 quire(1,x,y,t_c); 130 bool flag = false; 131 for(int i = 0;i <= 29;++i) 132 if(t_c & (1 << i)) 133 { 134 if(flag) printf(" "); 135 flag = true; 136 printf("%d",i+1); 137 } 138 if(flag) puts(""); 139 // print(); 140 } 141 } 142 } 143 return 0; 144 }