【题目描述】
先是在数轴区间 0 到10^9 (10的9次方)之间画上了白色。然后,这个区间的某一些部分又画上了黑色。然后某一些部分又画上白色,等等。请你找出经历M(1 <= M <= 5000)次重着色后,最长的白色区间。
【输入格式】
首行位N,以下N行位重着色的信息,每一行格式如下:ai bi ci 这里 ai ,bi 都是整数, ci 为字符'b' 或'w',用空格隔开。这三个参数描述:从ai到bi,着颜色ci, ('w'表示白,'b'表示黑),可以认为0 < ai <= bi < 10^9
【输出格式】
输出x,y (x < y)之间用空格隔开,表示最长的白色区间。假如有多个答案输出x最小的那个。
Sample Input4
1 999999997 b
40 300 w
300 634 w
43 47 b
47 634
Solution
很经典的离散化线段树。列几个坑点:
①以段建树要注意好区间开闭
②不要忘记0和1000000000这两个端点
③长度最大是按离散化前的长度定义的
Code
#include <cstdio> #include <algorithm> #include <map> #define N 5010 #define M 10010 using namespace std; map<int, int>mp; struct query {int l, r, c;}q[N]; int n, y[N<<1], m; struct seg {int l, r, lazy, mx, ls, rs;}t[M<<2]; inline void update(int p) { if(t[p].l == t[p].r) return ; if(t[p<<1].lazy == t[p<<1|1].lazy) t[p].lazy = t[p<<1].lazy; t[p].mx = max(t[p<<1].mx, max(t[p<<1|1].mx, t[p<<1].rs + t[p<<1|1].ls)); t[p].ls = (t[p<<1].lazy == 1)?(t[p<<1].ls + t[p<<1|1].ls):t[p<<1].ls; t[p].rs = (t[p<<1|1].lazy == 1)?(t[p<<1].rs + t[p<<1|1].rs):t[p<<1|1].rs; } inline void pushdown(int p) { if(t[p].l == t[p].r) return ; if(t[p].lazy) { t[p<<1].lazy = t[p<<1|1].lazy = t[p].lazy; if(t[p].lazy == 1) { t[p<<1].ls = t[p<<1].mx = t[p<<1].rs = y[t[p<<1].r + 1] - y[t[p<<1].l]; t[p<<1|1].ls = t[p<<1|1].mx = t[p<<1|1].rs = y[t[p<<1|1].r + 1] - y[t[p<<1|1].l]; }else { t[p<<1].ls = t[p<<1].mx = t[p<<1].rs = 0; t[p<<1|1].ls = t[p<<1|1].mx = t[p<<1|1].rs = 0; } t[p].lazy = 0; } } void build(int p, int l, int r) { t[p].l = l; t[p].r = r; t[p].lazy = 1; t[p].mx = t[p].ls = t[p].rs = y[r + 1] - y[l]; if(l == r) return ; int mid = (l + r)>>1; build(p<<1, l, mid); build(p<<1|1, mid + 1, r); } void ins(int p, int l, int r, int color) { if(l > r) return ; if(l <= t[p].l && t[p].r <= r) { t[p].lazy = color; if(color == 1) {t[p].mx = t[p].ls = t[p].rs = y[t[p].r + 1] - y[t[p].l];} else {t[p].mx = t[p].ls = t[p].rs = 0;} return ; } int mid = (t[p].l + t[p].r)>>1; pushdown(p); if(l <= mid) ins(p<<1, l, r, color); if(mid +1 <= r) ins(p<<1|1, l, r, color); update(p); } int final[M], cor[M], Q[M]; void dfs(int p) { if(t[p].l == t[p].r) { final[t[p].l] = (t[p].lazy == 1)?(y[t[p].l + 1] - y[t[p].l]):0; cor[t[p].l] = (t[p].lazy == 1)?1:0; return ; } pushdown(p); dfs(p<<1); dfs(p<<1|1); } int main() { scanf("%d", &n); char opt[5]; for(int i = 1; i <= n; ++i) { scanf("%d%d%s", &q[i].l, &q[i].r, opt); if(opt[0] == 'w') q[i].c = 1; else q[i].c = 2; y[(i<<1) - 1] = q[i].l; y[i<<1] = q[i].r; } y[n<<1|1] = 0; y[(n<<1|1) + 1] = 1000000000; sort(y+1, y+2*n+3); m = unique(y+1, y+(n<<1|1)+2) - y - 1; for(int i = 1; i <= m; ++i) mp[y[i]] = i; for(int i = 1; i <= n; ++i) {q[i].l = mp[q[i].l]; q[i].r = mp[q[i].r];} build(1, 1, m - 1); for(int i = 1; i <= n; ++i) ins(1, q[i].l, q[i].r - 1, q[i].c); dfs(1); for(int i = 2; i <= m - 1; ++i) final[i]+= final[i - 1]; int cont = 0; for(int i = 1; i <= m - 1; ++i) if(!cor[i]) Q[++cont] = i; Q[0] = 0; Q[++cont] = m; for(int i = 1; i <= cont; ++i) { int last = Q[i - 1] + 1, now = Q[i] - 1; if(last > now) continue; if(final[now] - final[last - 1] == t[1].mx) { printf("%d %d", y[last], y[now + 1]); break; } } return 0; }