URAL 1019. Line Painting 线段树 区间合并 离散化

来源:互联网 发布:qq游戏大厅mac版下载 编辑:程序博客网 时间:2024/05/22 14:52

题目来源:URAL 1019. Line Painting

题意:求最长的一段全部为白色的区间

思路:线段树成段更新 区间合并 离散化 这里对应的是一段区间 所以每次不是m+1 而是 l m 和 m r 了 另外我加上了0 和 10^9 这两个点

每一段区间(l, r)我记录的是l和r之间有多少条线段

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 50010;int sum[maxn<<2], lsum[maxn<<2], rsum[maxn<<2], co[maxn<<2];struct node{int x, v, id;}c[maxn*2];int num[maxn*2];char s[maxn][5];void pushup(int l, int r, int rt){int k = r-l+1;int m = (l+r) >> 1;lsum[rt] = lsum[rt<<1];rsum[rt] = rsum[rt<<1|1];if(lsum[rt] == num[m]-num[l])lsum[rt] += lsum[rt<<1|1];if(rsum[rt] == num[r]-num[m])rsum[rt] += rsum[rt<<1];sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);sum[rt] = max(sum[rt], rsum[rt<<1]+lsum[rt<<1|1]);}void build(int l, int r, int rt){sum[rt] = lsum[rt] = rsum[rt] = num[r]-num[l];co[rt] = -1;if(l + 1 == r)return;int m = (l+r) >> 1;build(l, m, rt<<1);build(m, r, rt<<1|1);//pushup(l, r, rt);}void pushdown(int l, int r, int rt){if(co[rt] != -1){int k = r-l+1;int m = (l + r) >> 1;sum[rt<<1] = co[rt]*(num[m]-num[l]);lsum[rt<<1] = co[rt]*(num[m]-num[l]);rsum[rt<<1] = co[rt]*(num[m]-num[l]);sum[rt<<1|1] = co[rt]*(num[r]-num[m]);lsum[rt<<1|1] = co[rt]*(num[r]-num[m]);rsum[rt<<1|1] = co[rt]*(num[r]-num[m]);co[rt<<1] = co[rt<<1|1] = co[rt];co[rt] = -1;}}int query(int l, int r, int rt, int a){if(l + 1 == r)return r;pushdown(l, r, rt);int m = (l+r) >> 1;//printf("*****%d %d %d %d %d\n", l, r, sum[rt<<1], sum[rt<<1|1], a);if(sum[rt<<1] >= a)return query(l, m, rt<<1, a);else if(rsum[rt<<1] + lsum[rt<<1|1] >= a)return query(m, r, rt<<1|1, a-rsum[rt<<1]);elsereturn query(m, r, rt<<1|1, a);}void update(int x, int y, int l, int r, int rt, int c){if(x == l && y == r){sum[rt] = lsum[rt] = rsum[rt] = c ? (num[r]-num[l]) : 0;co[rt] = c;return;}pushdown(l, r, rt);int m = (l+r) >> 1;if(y <= m)update(x, y, l, m, rt<<1, c);else if(x >= m)update(x, y, m, r, rt<<1|1, c);else{update(x, m, l, m, rt<<1, c);update(m, y, m, r, rt<<1|1, c);}pushup(l, r, rt);}bool cmp1(node a, node b){return a.x < b.x;}bool cmp2(node a, node b){return a.id < b.id;}int main(){int q;while(scanf("%d", &q) != EOF){for(int i = 0; i < q*2; i++){scanf("%d", &c[i].x);c[i].id = i;if(i&1)scanf("%s", s[(i-1)/2]);}sort(c, c+2*q, cmp1);int now = c[0].x, n = 2;num[1] = 0;for(int i = 0; i < q*2; i++){if(now != c[i].x){n++;now = c[i].x;}c[i].v = n;num[n] = now;}num[++n] = 1000000000;//for(int i = 1; i <= n; i++)//printf("***%d\n", num[i]);//printf("%d\n", n);sort(c, c+2*q, cmp2);build(1, n, 1);for(int i = 0; i < q; i++){int a = c[i<<1].v;int b = c[i<<1|1].v;int color = 1;if(s[i][0] == 'b')color = 0;update(a, b, 1, n, 1, color);//printf("***%d %d %d\n", a, b, sum[1]);}int ans = query(1, n, 1, sum[1]);printf("%d %d\n", num[ans]-sum[1], num[ans]);}return 0;}


 

0 0