HDU 1199 Color the Ball

HDU_1199

    根据数据的范围感觉离散化之后暴力染色也是可以的,更好一点的办法就是用线段树优化染色操作,最后将所有的标记都下传到叶子节点之后,再顺序扫一遍各个区间就可以得到结果了。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXD 4010
#define INF 0x3f3f3f3f
int N, tx[MAXD], to[4 * MAXD], X, color[4 * MAXD];
struct List
{
    int x, y, c;    
}list[MAXD];
void build(int cur, int x, int y)
{
    int mid = x + y >> 1, ls = cur << 1, rs = cur << 1 | 1;
    if(x == y)
    {
        to[cur] = 1;
        return ;    
    }
    to[cur] = -1;
    build(ls, x, mid), build(rs, mid + 1, y);
}
void init()
{
    int i;
    char b[5];
    for(i = 0; i < N; i ++)
    {
        scanf("%d%d%s", &list[i].x, &list[i].y, b);
        if(b[0] == 'w') list[i].c = 0;
        else list[i].c = 1;
        tx[i << 1] = list[i].x - 1, tx[i << 1 | 1] = list[i].y;
    }
    std::sort(tx, tx + 2 * N);
    X = 0;
    for(i = 1; i < 2 * N; i ++) if(tx[i] != tx[i - 1]) tx[++ X] = tx[i];
    build(1, 1, X);
}
void pushdown(int cur)
{
    if(to[cur] != -1)
    {
        to[cur << 1] = to[cur << 1 | 1] = to[cur];
        to[cur] = -1;
    }
}
void refresh(int cur, int x, int y, int s, int t, int c)
{
    int mid = x + y >> 1, ls = cur << 1, rs = cur << 1 | 1;
    if(x >= s && y <= t)
    {
        to[cur] = c;
        return ;
    }
    pushdown(cur);
    if(mid >= s) refresh(ls, x, mid, s, t, c);
    if(mid + 1 <= t) refresh(rs, mid + 1, y, s, t, c);
}
void down(int cur, int x, int y)
{
    int mid = x + y >> 1, ls = cur << 1, rs = cur << 1 | 1;
    if(x == y)
    {
        color[x] = to[cur];
        return;    
    }
    pushdown(cur);
    down(ls, x, mid), down(rs, mid + 1, y);
}
int BS(int x)
{
    int min = 0, mid, max = X;
    for(;;)
    {
        mid = min + max >> 1;
        if(min == mid) break;
        if(tx[mid] < x) min = mid;
        else max = mid;
    }    
    return mid + 1;
}
void solve()
{
    int i, ans, lx, rx, lt, rt;
    for(i = 0; i < N; i ++)
        refresh(1, 1, X, BS(list[i].x), BS(list[i].y), list[i].c);
    down(1, 1, X);
    ans = 0, lt = INF;
    for(i = 1; i <= X; i ++)
    {
        if(color[i] == 0)
        {
            lt = std::min(lt, tx[i - 1] + 1), rt = tx[i];
            if(rt - lt + 1 > ans)
                ans = rt - lt + 1, lx = lt, rx = rt;    
        }
        else
            lt = INF;
    }
    if(ans == 0) printf("Oh, my god\n");
    else printf("%d %d\n", lx, rx);
}
int main()
{
    while(scanf("%d", &N) == 1)
    {
        init();
        solve();    
    }
    return 0;    
}
原文地址:https://www.cnblogs.com/staginner/p/2658092.html