hdu 1199 Color the ball(线段树离散化区间染色)

来源:互联网 发布:js根据id隐藏div 编辑:程序博客网 时间:2024/05/22 10:05

题目链接:点击打开链接


线段树离散化区间染色。

数据范围是int最大值,肯定要离散化,离散化时要注意加点。

举几个个例子:

1. 输入 1,2,4,5,如果离散成1,2,3,4那么本来最长区间是1到2,离散后就变成1到4了,这就要在2和4之间加点。

2. 输入 1 5 w,3 5 b,最长区间应是1到2,但是不加点的话没有点表示2,得不到1到2这个结果,需要添加点2

3. 输入  1 5 w,1 3 b,最长区间是4到5,同理需要加4这个点


综上,离散化的步骤是先对原数组排序(代码中用tmp表示),然后加上这两句:

        if(tmp[i]-tmp[i-1]>1) Hash[++k]=tmp[i]-1;
        if(tmp[i]-tmp[i-1]>2) Hash[++k]=tmp[i-1]+1;


另外统计结果的方法是遍历叶子节点,找最长区间,所以此线段树不需要pushup,只需要能把改变传到下面的pushdown即可。


代码:

#include <iostream>#include <cstring>#include <cstdio>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#include <algorithm>using namespace std;#define MAX 30000int Hash[MAX*2];int res[MAX<<2];int col[MAX<<2];int ans[MAX*2];struct seg{    int s,t;    int c;}p[MAX];void pushdown(int rt){    if(col[rt]){        col[rt<<1]=col[rt<<1|1]=col[rt];        res[rt<<1]=res[rt<<1|1]=col[rt];        col[rt]=0;    }}void build(int l,int r,int rt){    col[rt]=0;    res[rt]=2;    if(l==r) return ;    int m=(l+r)>>1;    build(lson);    build(rson);}void update(int L,int R,int c,int l,int r,int rt){    if(L<=l&&R>=r){        res[rt]=c;        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(l==r){        ans[l]=res[rt];        return ;    }       int m=(l+r)>>1;    query(lson);    query(rson);}void solve(int n){    long long tmp[MAX*2];    int len=0;    for(int i=1;i<=n;i++){        char c[4];        scanf("%d%d%s",&p[i].s,&p[i].t,c);        tmp[++len]=p[i].s;        tmp[++len]=p[i].t;        if(c[0]=='w') p[i].c=1;        else p[i].c=2;    }    sort(tmp+1,tmp+len+1);    int k=0;    Hash[++k]=tmp[1];    for(int i=2;i<=len;i++){        Hash[++k]=tmp[i];        if(tmp[i]-tmp[i-1]>1) Hash[++k]=tmp[i]-1;        if(tmp[i]-tmp[i-1]>2) Hash[++k]=tmp[i-1]+1;    }    sort(Hash+1,Hash+k+1);    len=unique(Hash+1,Hash+k+1)-Hash-1;    build(1,len,1);    for(int i=1;i<=n;i++){        int s=lower_bound(Hash+1,Hash+len+1,p[i].s)-Hash;        int t=lower_bound(Hash+1,Hash+len+1,p[i].t)-Hash;        if(s>t) continue;        update(s,t,p[i].c,1,len,1);    }    query(1,len,1);    int answer=-1;    int l=0,r=0;    bool flag=0;    for(int i=1;i<=len;i++){        int j=i;        if(ans[i]==1){          flag=1;          int tmp=0;          while(j<len&&ans[j+1]==1){            j++;          }          tmp=Hash[j]-Hash[i];          if(tmp>answer){                answer=tmp;                l=Hash[i];                r=Hash[j];          }        }        i=j;    }    if(!flag) printf("0\n");    else printf("%d %d\n",l,r);}int main(){    int n;    while(~scanf("%d",&n)){        solve(n);    }    return 0;}



0 0
原创粉丝点击