POJ 2528 (线段树+离散化)

来源:互联网 发布:淘宝怎么添加客服号 编辑:程序博客网 时间:2024/06/02 05:30
题意:在墙上贴海报,给出每次所贴的区间,问最后能看到几张海报。
思路:线段树,但是所给区间长度最大为1000000,必须离散化处理。
离散化:把所有点按序排列;去掉重复的点;给间隔大于一的两数之间添加一个数(避免错误);排序;查找出左右区间的位置(即离散化后所对应的数值)
线段树:用模板即可解决(一个变量名写错,调试了一中午,呜呜~~温温好失败)

AC代码:
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define maxx 10005int x[maxx<<2],col[maxx<<4],li[maxx],ri[maxx];bool flag[maxx];int n,m,ans;int Bsearch(int key){  int left=0,right=m-1,mid;  while(left<=right)  {   mid=(left+right)>>1;   if(x[mid]==key) return mid;   if(x[mid]<key)   left=mid+1;   else   right=mid-1;  }  return -1;}void pushdown(int rt){  if(col[rt]!=-1)  {    col[rt<<1]=col[rt];    col[rt<<1|1]=col[rt];    col[rt]=-1;  }}void update(int left,int right,int c,int l,int r,int rt){  if(left<=l&&right>=r)  {    col[rt]=c;    return;  }  pushdown(rt);  int mid=(l+r)>>1;  if(left<=mid)  update(left,right,c,lson);  if(right>mid)  update(left,right,c,rson);}void query(int l,int r,int rt){   if(col[rt]!=-1)   {     if(!flag[col[rt]])     ans++;     flag[col[rt]]=1;     return;   }   if(l==r) return;   int mid=(l+r)>>1;   query(lson);   query(rson);}int main(){  int t;  scanf("%d",&t);  while(t--)  {ans=0;memset(col,-1,sizeof(col));memset(flag,0,sizeof(flag));    scanf("%d",&n);    for(int i=0;i<n;i++)    scanf("%d%d",&li[i],&ri[i]);int nn=0;    for(int i=0;i<n;i++)    {     x[nn++]=li[i];     x[nn++]=ri[i];    }    sort(x,x+nn);m=1;    for(int i=1;i<nn;i++)   {     if(x[i]!=x[i-1]) x[m++]=x[i];   }  for(int i=m-1;i>=0;i--)  {   if(x[i]!=(x[i-1]+1))   x[m++]=x[i-1]+1;  }  sort(x,x+m);  for(int i=0;i<n;++i) {   int l=Bsearch(li[i]);   int r=Bsearch(ri[i]);   update(l,r,i,0,m-1,1); }   query(0,m-1,1);   printf("%d\n",ans);  }  return 0;}




0 0