poj2528(线段树区间染色)

来源:互联网 发布:sqlserver增量备份 编辑:程序博客网 时间:2024/05/22 04:40

链接:点击打开链接

题意:给出n张海报,问最后能看到几张海报,具体看图


代码:

#include <vector>#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int siz=50005;int n,x[siz],y[siz],vis[siz],col[siz],tree[siz<<2];void pushdown(int rt){    if(tree[rt]){        tree[rt<<1]=tree[rt];        tree[rt<<1|1]=tree[rt];        tree[rt]=0;    }}void Change(int L,int R,int p,int l,int r,int rt){    if(L<=l&&r<=R){        tree[rt]=p;        return;    }    pushdown(rt);    int m=(l+r)>>1;    if(L<=m)    Change(L,R,p,l,m,rt<<1);    if(R>m)    Change(L,R,p,m+1,r,rt<<1|1);}void query(int l,int r,int rt){    if(l==r){        if(tree[rt])        vis[tree[rt]]=1;        return;                                 //只查询叶子节点    }    pushdown(rt);    int m=(l+r)>>1;    query(l,m,rt<<1);    query(m+1,r,rt<<1|1);}                                               //其实就是一个不回溯的线段树int comprass(int op){    int i,tmp;    sort(col,col+op);    tmp=op;    for(i=1;i<tmp;i++){        if(col[i]-col[i-1]>1)        col[op++]=(col[i]-1);    }    sort(col,col+op);    tmp=unique(col,col+op)-col;    for(i=1;i<=n;i++){        x[i]=lower_bound(col,col+tmp,x[i])-col+1;        y[i]=lower_bound(col,col+tmp,y[i])-col+1;    }    return tmp;}int main(){    int t,i,j,op,ans;    scanf("%d",&t);    while(t--){        memset(col,0,sizeof(col));        memset(vis,0,sizeof(vis));        memset(tree,0,sizeof(tree));        scanf("%d",&n);        op=0;        for(i=1;i<=n;i++){                      //直接离散化后区间覆盖            scanf("%d%d",&x[i],&y[i]);          //离散化要注意之前不相邻的元素,离散化后也            col[op++]=x[i];                     //能相邻            col[op++]=y[i];        }        op=comprass(op);        for(i=1;i<=n;i++)        Change(x[i],y[i],i,1,op,1);        query(1,op,1);        ans=0;        for(i=1;i<=n;i++)        if(vis[i])        ans++;        printf("%d\n",ans);    }    return 0;}