zoj2301Color the Ball(线段树,离散化,成段更新)

来源:互联网 发布:西工大编程 编辑:程序博客网 时间:2024/06/05 20:26

题目链接:zoj2301

和poj2528做法基本一样,建议先做poj的那道题

/*zoj2301Color the Ball 线段树区间成段更新,离散化题目大意:    一些连续的球,编号从1~2^31-1,最初球都是黑色的输入涂色的区间和要涂的颜色,将区间内的球都涂色(端点处的球也涂色)输出连续的且都是白色球的最长的区间,相同的话输出坐标小的*/#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1const int N = 4000;bool hash[N<<3];int col[N<<4];int X[N<<2];struct node{    int x,y,c;    node(){}    node(int a, int b, int cc):x(a),y(b),c(cc){}}s[N<<2];void pushdown(int rt){    if(col[rt] != -1)    {        col[rt<<1] = col[rt<<1|1] = col[rt];        col[rt] = -1;    }}void update(int L, int R, int c, int l, int r, int rt){    if(L <= l && r <= R)    {        col[rt] = c;        return;    }    pushdown(rt);    int m = (l+r) >> 1;    if(L <= m) update(L, R, c, lson);    if(R > m) update(L, R, c, rson);}void query(int l, int r, int rt){    if(col[rt] == 1)    {        for(int i = l; i <= r; i ++)            hash[i] = true;        return;    }    if(col[rt] == 0) return;    int m = (l+r) >> 1;    query(lson);    query(rson);}int main(){    int i,n,j;    while(~scanf("%d",&n))    {        char a[3];        int x,y;        memset(col, 0, sizeof(col));//0表示黑色        memset(hash, false, sizeof(hash));        int m = 0;        for(i = 0; i < n; i ++)        {            scanf("%d%d%s",&x,&y,a);            int c = a[0]=='b'?0:1;            s[i] = node(x, y, c);            X[m++] = x;            X[m++] = y;        }        sort(X, X+m);        int tot = 1;        for(i = 1; i < m; i ++)            if(X[i] != X[i-1]) X[tot++] = X[i];        for(i = tot - 1; i > 0; i --)            if(X[i] != X[i-1] + 1) X[tot++] = X[i-1] + 1;        sort(X, X+tot);        for(i = 0; i < n; i ++)        {            int l = lower_bound(X, X+tot, s[i].x) - X;            int r = lower_bound(X, X+tot, s[i].y) - X;            update(l+1, r+1, s[i].c, 1, tot, 1);        }        query(1, tot, 1);        int ax,ay,alen = -1;        for(i = 0; i <= tot; i ++)//查找长度最长且坐标最小的区间        {            if(hash[i])            {                for(j = i; j <= tot; j ++)                    if(!hash[j]) break;                if(X[j-2] - X[i-1] > alen)                {                    ax = X[i-1]; ay = X[j-2];                    alen = ay - ax;                }                i = j - 1;            }        }        printf("%d %d\n",ax,ay);    }    return 0;}


0 0
原创粉丝点击