POJ 2528 Mayor's posters.

来源:互联网 发布:机明石墨电极编程视频 编辑:程序博客网 时间:2024/06/06 19:09

~~~~

一直MLE,才发现要写离散化操作。其他就是线段树的成段更新(每次用不同标记去更新区间),最后统计下有多少种标记就OK了。

题目链接:http://poj.org/problem?id=2528

大牛写的很详细,请戳:http://blog.csdn.net/metalseed/article/details/8041334

~~~~

#include<cstdio>#include<cstring>#include<algorithm>#define N 11111#define lson rt<<1,s,m#define rson rt<<1|1,m+1,eusing namespace std;int x[N<<2]; //因为有离散化操作,注意数组大小,否则会RE。int ans[N<<2];int s[N],e[N];int tre[N<<4];void pushdown(int rt,int m){    if(tre[rt])    {        tre[rt<<1]=tre[rt<<1|1]=tre[rt];        tre[rt]=0;    }}void update(int l,int r,int val,int rt,int s,int e){    if(l<=s && r>=e)    {        tre[rt] = val;        return ;    }    pushdown(rt,e-s+1);    int m=(s+e)>>1;    if(r<=m) update(l,r,val,lson);    else if(l>m) update(l,r,val,rson);    else    {        update(l,m,val,lson);        update(m+1,r,val,rson);    }}int query(int pos,int rt,int s,int e){    if(s==e)        return tre[rt];    pushdown(rt,e-s+1);    int m=(s+e)>>1;    if(pos<=m) query(pos,lson);    else query(pos,rson);}int bin(int key,int ma){    int l=0,r=ma,m=0;    while(l<=r)    {        m=(l+r)>>1;        if(x[m]==key) return m;        else if(x[m]>key) r=m-1;        else l=m+1;    }    //return -1;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int m;        scanf("%d",&m);        int n=0;        for(int i=1;i<=m;i++)        {            scanf("%d%d",&s[i],&e[i]);            x[n++]=s[i];            x[n++]=e[i];        }        int cnt=1;        sort(x,x+n);        //删去重复的元素,        for(int i=1;i<n;i++)            if(x[i]!=x[i-1]) x[cnt++]=x[i];        //离散化技巧:凸显间隔(否则可能会有问题)。        for(int i=cnt-1;i>0;i--)            if(x[i]!=x[i-1]+1) x[cnt++]=x[i-1]+1;        //再一次排序,便于后面二分离散化。        sort(x,x+cnt);        memset(tre,0,sizeof(tre)); //相当于建树过程        for(int i=1;i<=m;i++)        {            int l=bin(s[i],cnt-1);            int r=bin(e[i],cnt-1);            update(l,r,i,1,0,cnt-1); //依次标记        }        int q=0;        for(int i=0;i<cnt;i++)        {            int k=query(i,1,0,cnt-1);            if(k) ans[q++]=k;  //~~        }        sort(ans,ans+q);        int tot=1;        for(int i=1;i<q;i++)            if(ans[i]!=ans[i-1]) tot++;        printf("%d\n",tot);    }    return 0;}


0 0