离散化时将左右节点 (l[i],r[i]) 和左节点减1 (l[i]-1) 全部加入,离散化
建树时用段树方法比较方便,即叶子节点表示一个区间而不是一个值,很多边界问题就不用考虑了
1
#include
<
cstdio
>
2 #include < cstring >
3 #include < algorithm >
4 using namespace std;
5 #define M 6060
6
7 int dis[M],m;
8 int Find( int x){
9 int low = 0 ,high = m;
10 int mid = (low + high) >> 1 ;
11 while ( true ){
12 if (dis[mid] == x){
13 return mid;
14 } else if (dis[mid] > x){
15 high = mid - 1 ;
16 } else if (dis[mid] < x){
17 low = mid + 1 ;
18 }
19 mid = (low + high) >> 1 ;
20 }
21 }
22
23 struct Seg_Tree{
24 int left,right;
25 int lm,rm,len,lp;
26 bool col,flag;
27 // left,right 左右值(离散)
28 // lm,rm 表示该区间最左端和最右端的白色球区间的长度(非离散)
29 // len 表示该区间的最大长度(非离散)
30 // lp 表示该区间最大长度开始的位置(非离散)
31 // col 表示该区间是否为白色
32 // flag 传说中的lazy标记
33 int Glen(){
34 // 该区间的总长度(非离散)
35 return dis[right] - dis[left];
36 }
37 }STree[M << 2 ];
38
39 void Build( int left, int right, int idx){
40 STree[idx].left = left;
41 STree[idx].right = right;
42 STree[idx].lm = 0 ;
43 STree[idx].rm = 0 ;
44 STree[idx].lp = dis[left];
45 STree[idx].len = 0 ;
46 STree[idx].flag = false ;
47 STree[idx].col = false ;
48 // 叶子节点是一个区间,处理长度时会方便很多
49 // 注意下面递归时范围的不同
50 if (right - left == 1 ) return ;
51 int mid = (left + right) >> 1 ;
52 Build(left,mid,idx << 1 );
53 Build(mid,right,idx << 1 | 1 );
54 }
55
56 void Update( int idx, bool val){
57 STree[idx].col = val;
58 STree[idx].flag = true ;
59 if (val) STree[idx].len = STree[idx].Glen();
60 else STree[idx].len = 0 ;
61 STree[idx].lm = STree[idx].rm = STree[idx].len;
62 STree[idx].lp = dis[STree[idx].left];
63 }
64
65 void Modify( int left, int right, int idx, bool val){
66 if (STree[idx].left == left && STree[idx].right == right){
67 Update(idx,val);
68 return ;
69 }
70
71 if (STree[idx].flag){
72 STree[idx].flag = false ;
73 Update(idx << 1 ,STree[idx].col);
74 Update(idx << 1 | 1 ,STree[idx].col);
75 }
76
77 int mid = (STree[idx].left + STree[idx].right) >> 1 ;
78 if (right <= mid){
79 Modify(left,right,idx << 1 ,val);
80 } else if (left >= mid){
81 Modify(left,right,idx << 1 | 1 ,val);
82 } else {
83 Modify(left,mid,idx << 1 ,val);
84 Modify(mid,right,idx << 1 | 1 ,val);
85 }
86
87 if (STree[idx << 1 ].len >= STree[idx << 1 | 1 ].len){
88 STree[idx].len = STree[idx << 1 ].len;
89 STree[idx].lp = STree[idx << 1 ].lp;
90 } else {
91 STree[idx].len = STree[idx << 1 | 1 ].len;
92 STree[idx].lp = STree[idx << 1 | 1 ].lp;
93 }
94 if (STree[idx << 1 ].rm + STree[idx << 1 | 1 ].lm > STree[idx].len){
95 STree[idx].len = STree[idx << 1 ].rm + STree[idx << 1 | 1 ].lm;
96 STree[idx].lp = dis[STree[idx << 1 ].right] - STree[idx << 1 ].rm;
97 }
98
99 STree[idx].lm = STree[idx << 1 ].lm;
100 if (STree[idx << 1 ].len == STree[idx << 1 ].Glen()){
101 STree[idx].lm = STree[idx << 1 ].len + STree[idx << 1 | 1 ].lm;
102 }
103 STree[idx].rm = STree[idx << 1 | 1 ].rm;
104 if (STree[idx << 1 | 1 ].len == STree[idx << 1 | 1 ].Glen()){
105 STree[idx].rm = STree[idx << 1 | 1 ].len + STree[idx << 1 ].rm;
106 }
107 }
108
109 int l[ 2010 ],r[ 2010 ];
110 bool c[ 2010 ];
111 int main(){
112 int n;
113 while ( ~ scanf( " %d " , & n)){
114 for ( int i = 0 ;i < n;i ++ ){
115 char col[ 5 ];
116 scanf( " %d%d %s " , & l[i], & r[i],col);
117 if (col[ 0 ] == ' w ' ){
118 c[i] = true ;
119 } else if (col[ 0 ] == ' b ' ){
120 c[i] = false ;
121 }
122 // l[i],r[i],l[i]-1 加入离散
123 // 将l[i]-1改为r[i]+1也可,但要注意数据范围
124 dis[i * 3 ] = l[i];
125 dis[i * 3 + 1 ] = r[i];
126 dis[i * 3 + 2 ] = l[i] - 1 ;
127 }
128
129 sort(dis,dis + n * 3 );
130 m = 0 ;
131 for ( int i = 1 ;i < n * 3 ;i ++ ){
132 if (dis[i] == dis[i - 1 ]) continue ;
133 dis[ ++ m] = dis[i];
134 }
135
136 Build( 0 ,m, 1 );
137 for ( int i = 0 ;i < n;i ++ ){
138 // 插入时将左值减1,全部转化为区间
139 int ll = Find(l[i]) - 1 ;
140 int rr = Find(r[i]);
141 Modify(ll,rr, 1 ,c[i]);
142 }
143 if (STree[ 1 ].len == 0 ){
144 puts( " Oh, my god " );
145 } else {
146 printf( " %d %d\n " ,STree[ 1 ].lp + 1 ,STree[ 1 ].lp + STree[ 1 ].len);
147 }
148 }
149 }
2 #include < cstring >
3 #include < algorithm >
4 using namespace std;
5 #define M 6060
6
7 int dis[M],m;
8 int Find( int x){
9 int low = 0 ,high = m;
10 int mid = (low + high) >> 1 ;
11 while ( true ){
12 if (dis[mid] == x){
13 return mid;
14 } else if (dis[mid] > x){
15 high = mid - 1 ;
16 } else if (dis[mid] < x){
17 low = mid + 1 ;
18 }
19 mid = (low + high) >> 1 ;
20 }
21 }
22
23 struct Seg_Tree{
24 int left,right;
25 int lm,rm,len,lp;
26 bool col,flag;
27 // left,right 左右值(离散)
28 // lm,rm 表示该区间最左端和最右端的白色球区间的长度(非离散)
29 // len 表示该区间的最大长度(非离散)
30 // lp 表示该区间最大长度开始的位置(非离散)
31 // col 表示该区间是否为白色
32 // flag 传说中的lazy标记
33 int Glen(){
34 // 该区间的总长度(非离散)
35 return dis[right] - dis[left];
36 }
37 }STree[M << 2 ];
38
39 void Build( int left, int right, int idx){
40 STree[idx].left = left;
41 STree[idx].right = right;
42 STree[idx].lm = 0 ;
43 STree[idx].rm = 0 ;
44 STree[idx].lp = dis[left];
45 STree[idx].len = 0 ;
46 STree[idx].flag = false ;
47 STree[idx].col = false ;
48 // 叶子节点是一个区间,处理长度时会方便很多
49 // 注意下面递归时范围的不同
50 if (right - left == 1 ) return ;
51 int mid = (left + right) >> 1 ;
52 Build(left,mid,idx << 1 );
53 Build(mid,right,idx << 1 | 1 );
54 }
55
56 void Update( int idx, bool val){
57 STree[idx].col = val;
58 STree[idx].flag = true ;
59 if (val) STree[idx].len = STree[idx].Glen();
60 else STree[idx].len = 0 ;
61 STree[idx].lm = STree[idx].rm = STree[idx].len;
62 STree[idx].lp = dis[STree[idx].left];
63 }
64
65 void Modify( int left, int right, int idx, bool val){
66 if (STree[idx].left == left && STree[idx].right == right){
67 Update(idx,val);
68 return ;
69 }
70
71 if (STree[idx].flag){
72 STree[idx].flag = false ;
73 Update(idx << 1 ,STree[idx].col);
74 Update(idx << 1 | 1 ,STree[idx].col);
75 }
76
77 int mid = (STree[idx].left + STree[idx].right) >> 1 ;
78 if (right <= mid){
79 Modify(left,right,idx << 1 ,val);
80 } else if (left >= mid){
81 Modify(left,right,idx << 1 | 1 ,val);
82 } else {
83 Modify(left,mid,idx << 1 ,val);
84 Modify(mid,right,idx << 1 | 1 ,val);
85 }
86
87 if (STree[idx << 1 ].len >= STree[idx << 1 | 1 ].len){
88 STree[idx].len = STree[idx << 1 ].len;
89 STree[idx].lp = STree[idx << 1 ].lp;
90 } else {
91 STree[idx].len = STree[idx << 1 | 1 ].len;
92 STree[idx].lp = STree[idx << 1 | 1 ].lp;
93 }
94 if (STree[idx << 1 ].rm + STree[idx << 1 | 1 ].lm > STree[idx].len){
95 STree[idx].len = STree[idx << 1 ].rm + STree[idx << 1 | 1 ].lm;
96 STree[idx].lp = dis[STree[idx << 1 ].right] - STree[idx << 1 ].rm;
97 }
98
99 STree[idx].lm = STree[idx << 1 ].lm;
100 if (STree[idx << 1 ].len == STree[idx << 1 ].Glen()){
101 STree[idx].lm = STree[idx << 1 ].len + STree[idx << 1 | 1 ].lm;
102 }
103 STree[idx].rm = STree[idx << 1 | 1 ].rm;
104 if (STree[idx << 1 | 1 ].len == STree[idx << 1 | 1 ].Glen()){
105 STree[idx].rm = STree[idx << 1 | 1 ].len + STree[idx << 1 ].rm;
106 }
107 }
108
109 int l[ 2010 ],r[ 2010 ];
110 bool c[ 2010 ];
111 int main(){
112 int n;
113 while ( ~ scanf( " %d " , & n)){
114 for ( int i = 0 ;i < n;i ++ ){
115 char col[ 5 ];
116 scanf( " %d%d %s " , & l[i], & r[i],col);
117 if (col[ 0 ] == ' w ' ){
118 c[i] = true ;
119 } else if (col[ 0 ] == ' b ' ){
120 c[i] = false ;
121 }
122 // l[i],r[i],l[i]-1 加入离散
123 // 将l[i]-1改为r[i]+1也可,但要注意数据范围
124 dis[i * 3 ] = l[i];
125 dis[i * 3 + 1 ] = r[i];
126 dis[i * 3 + 2 ] = l[i] - 1 ;
127 }
128
129 sort(dis,dis + n * 3 );
130 m = 0 ;
131 for ( int i = 1 ;i < n * 3 ;i ++ ){
132 if (dis[i] == dis[i - 1 ]) continue ;
133 dis[ ++ m] = dis[i];
134 }
135
136 Build( 0 ,m, 1 );
137 for ( int i = 0 ;i < n;i ++ ){
138 // 插入时将左值减1,全部转化为区间
139 int ll = Find(l[i]) - 1 ;
140 int rr = Find(r[i]);
141 Modify(ll,rr, 1 ,c[i]);
142 }
143 if (STree[ 1 ].len == 0 ){
144 puts( " Oh, my god " );
145 } else {
146 printf( " %d %d\n " ,STree[ 1 ].lp + 1 ,STree[ 1 ].lp + STree[ 1 ].len);
147 }
148 }
149 }