Ural_1019. Line Painting(线段树)

  /*额滴神啊。。。调了整整一晚上。简单染色问题,染完色后再扫描一遍,找出最大的
连续是白色的序列。开始必须把0, 109 这两个点加上去。就因为这个都快调shi了。。。扫
描的时候用一个数组记录染色后区间的颜色。然后找连续颜色是白色的最大区间。

数据有点大,用离散化吧。
*/

//My Code:

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>

#define L(t) t << 1
#define R(t) t << 1 | 1

using namespace std;


const int N = 10007;

struct tree {
int l, r;
int col;
} tree[N<<2];

struct axis {
int s, e;
int col;
} ax[N];

int p[N], t[N], T, col[N];

int get_pos(int x) {
int l = 0, r = T, mid;
while(l <= r) {
mid = (l + r) >> 1;
if(p[mid] == x) return mid;
else if(p[mid] > x) r = mid -1;
else l = mid + 1;
}
}

void creat(int t, int l, int r) {
tree[t].l = l;
tree[t].r = r;
tree[t].col = 1;
if(l + 1 == r) return ;
int mid = (l + r) >> 1;
creat(L(t), l, mid);
creat(R(t), mid, r);
}

void updata(int t, int l, int r, int col) {
if(tree[t].l >= l && tree[t].r <= r) {
//printf("%d %d %d\n", tree[t].l, tree[t].r, col);
tree[t].col = col;
return ;
}
if(tree[t].col >= 0 && tree[t].col != col) {
tree[L(t)].col = tree[R(t)].col = tree[t].col;
tree[t].col = -1;
}
int mid = (tree[t].l + tree[t].r) >> 1;
if(l >= mid) updata(R(t), l, r, col);
else if(r <= mid) updata(L(t), l, r, col);
else {
updata(L(t), l, mid, col);
updata(R(t), mid, r, col);
}
}

void query(int t, int l, int r) {
//printf("%d\n", tree[t].col);
if(tree[t].col >= 0) {
//printf("%d %d %d\n", tree[t].l, tree[t].r, tree[t].col);
for(int i = tree[t].l; i < tree[t].r; i++) {
col[i] = tree[t].col;
}
return ;
}
int mid = (tree[t].l + tree[t].r) >> 1;
if(l >= mid) query(R(t), l, r);
else if(r <= mid) query(L(t), l, r);
else {
query(L(t), l, mid);
query(R(t), mid, r);
}
}

int main() {
//freopen("data.in", "r", stdin);

int n, i, tmp, x, y;
char c;
while(~scanf("%d", &n)) {
memset(col, 1, sizeof(col));
memset(t, 0, sizeof(t));
memset(p, 0, sizeof(p));
memset(tree, 0, sizeof(tree));

ax[0].s = 0; ax[0].e = 1e9; ax[0].col = 1;
T = 0; t[T++] = 0; t[T++] = 1e9;
for(i = 1; i <= n; i++) {
scanf("%d%d %c", &ax[i].s, &ax[i].e, &c);
if(c == 'w') ax[i].col = 1;
else ax[i].col = 0;
t[T++] = ax[i].s;
t[T++] = ax[i].e;
}
sort(t, t+T+1);
tmp = t[0]; T = 0; p[T++] = tmp;
for(i = 1; i <= n+n+2; i++) {
//printf("%d ", t[i]);
if(tmp != t[i]) {
tmp = t[i];
p[T++] = tmp;
}
}
//cout << endl;

/*for(i = 0; i <= T; i++) {
printf("%d ", p[i]);
}
cout << endl;
*/
T--; creat(1, 0, T);
for(i = 0; i <= n; i++) {
x = get_pos(ax[i].s);
y = get_pos(ax[i].e);
//printf("%d %d %d %d %d\n", ax[i].s, ax[i].e, x, y, ax[i].col);
updata(1, x, y, ax[i].col);
}
query(1, 0, T);
int s = 0, e = 0, ts, te;
for(i = 0; i <= T; i++) {
ts = p[i];
while(col[i] == 1) i++;
te = p[i];
if(te - ts > e - s) {
e = te; s = ts;
}
}
printf("%d %d\n", s, e);
}
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值