poj 2528 线段树+离散化+有颜色的区间覆盖

来源:互联网 发布:宏观数据 编辑:程序博客网 时间:2024/05/01 14:15

    区间覆盖,和一般的区间覆盖问题的区别是每个覆盖的区间是有颜色的,最后要输出可见的颜色个数。对于每个区间操作,我们可以采用懒标记的思想,等到有其他区间覆盖过来时,将该区间的颜色向下传递。具体见代码。

#include <cstdio>#include <algorithm>#include <iostream>using namespace std;struct node{    int l,r;};node a[10002];int n,m,q;int lisan[20002],f[80002];void build(int l,int r,int k){    q=max(q,k);    f[k]=-2;                                        //f[k]=-2表示k结点所在的区间还没有被覆盖    if (l==r) return;    int mid=(l+r)>>1;    build(l,mid,2*k);    build(mid+1,r,2*k+1);}void push(int k){    if (f[k]>-1)    {        f[2*k]=f[2*k+1]=f[k];    }}void change(int l,int r,int k,int L,int R,int VAL){    if ((L<=l)&&(r<=R))    {        f[k]=VAL;                                    //直接用该点的颜色覆盖所在区间        return;    }    push(k);                                        //将颜色向下传递    int mid=(l+r)>>1;    if (R<=mid) change(l,mid,2*k,L,R,VAL);    else if (L>mid) change(mid+1,r,2*k+1,L,R,VAL);    else    {        change(l,mid,2*k,L,mid,VAL);        change(mid+1,r,2*k+1,mid+1,R,VAL);    }    if ((f[2*k]==-1)||(f[2*k+1]==-1)) f[k]=-1;        //f[k]=-1表示该区间有多种颜色    else if (f[2*k]==-2) f[k]=f[2*k+1];    else if (f[2*k+1]==-2) f[k]=f[2*k];    else if (f[2*k]==f[2*k+1]) f[k]=f[2*k];    else f[k]=-1;}bool work(int l,int r,int k,int L,int R,int VAL){    if ((f[k]!=-1)&&(f[k]!=VAL)) return 0;    if (f[k]==VAL) return 1;                               //找到该颜色    int mid=(l+r)>>1;    if (R<=mid) return work(l,mid,2*k,L,R,VAL);    else if (L>mid) return work(mid+1,r,2*k+1,L,R,VAL);    else    {        int t=work(l,mid,2*k,L,mid,VAL);        if (t) return t;        else return work(mid+1,r,2*k+1,mid+1,R,VAL);    }}int main(){    int t;    scanf("%d",&t);    while (t--)    {        q=0;        scanf("%d",&n);        m=0;        for (int i=0;i<n;i++)        {            scanf("%d%d",&a[i].l,&a[i].r);            lisan[m++]=a[i].l;            lisan[m++]=a[i].r;        }        sort(lisan,lisan+m);        m=unique(lisan,lisan+m)-lisan;        build(0,m-1,1);        for (int i=0;i<n;i++)        {            int l=lower_bound(lisan,lisan+m,a[i].l)-lisan;            int r=lower_bound(lisan,lisan+m,a[i].r)-lisan;            change(0,m-1,1,l,r,i);        }        int ans=0;        for (int i=0;i<n;i++)        {            int l=lower_bound(lisan,lisan+m,a[i].l)-lisan;            int r=lower_bound(lisan,lisan+m,a[i].r)-lisan;            ans+=work(0,m-1,1,l,r,i);        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击