线段树成段更新 poj 2528 Mayor's posters

线段树成段更新 poj  2528  Mayor's posters

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

题目大意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报

思路:离散化+线段树成段更新+hash

普通离散化有缺陷,所以我们在排序后的数组上加一些处理,比如说[1,2,6,10]
如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了.
线段树功能:update:成段替换 query:简单hash

代码如下:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 using namespace std;
  5 #define lson l,m,rt<<1
  6 #define rson m+1,r,rt<<1|1
  7 #define N 20010
  8 int tree[N<<4],li[N],ri[N],hash[N<<2],tmp[N<<2];
  9 int ans;
 10 int bin(int x,int n)
 11 {
 12     int low=0,high=n-1;
 13     while(low<=high)
 14     {
 15         int mid=(low+high)>>1;
 16         if(tmp[mid]==x)
 17             return mid;
 18         else if(tmp[mid]<x)
 19             low=mid+1;
 20         else
 21             high=mid-1;
 22     }
 23     return -1;
 24 }
 25 void pushdown(int rt)
 26 {
 27     if(tree[rt]!=-1)
 28     {
 29         tree[rt<<1]=tree[rt<<1|1]=tree[rt];
 30         tree[rt]=-1;
 31     }
 32 }
 33 void update(int L,int R,int c,int l,int r,int rt)
 34 {
 35     if(L<=l&&R>=r)
 36     {
 37         tree[rt]=c;
 38         return ;
 39     }
 40     pushdown(rt);
 41     int m=(l+r)>>1;
 42     if(L<=m)
 43         update(L,R,c,lson);
 44     if(R>m)
 45         update(L,R,c,rson);
 46 }
 47 void query(int l,int r,int rt)
 48 {
 49     if(tree[rt]!=-1)
 50     {
 51         if(!hash[tree[rt]])
 52         {
 53             ans++;
 54             hash[tree[rt]]=1;
 55         }
 56         return ;
 57     }
 58     if(l==r)
 59         return ;
 60     int m=(l+r)>>1;
 61     query(lson);
 62     query(rson);
 63 }
 64 int main()
 65 {
 66     int t,i,j,n;
 67     scanf("%d",&t);
 68     while(t--)
 69     {
 70         scanf("%d",&n);
 71         int k=0;
 72         for(i=0;i<n;i++)
 73         {
 74             scanf("%d%d",&li[i],&ri[i]);
 75             tmp[k++]=li[i];
 76             tmp[k++]=ri[i];
 77         }
 78         sort(tmp,tmp+k);
 79         int m=1;
 80         for(i=1;i<k;i++)
 81             if(tmp[i]!=tmp[i-1])
 82                 tmp[m++]=tmp[i];
 83         for(i=m-1;i>0;i--)
 84             if(tmp[i]!=tmp[i-1]+1)
 85                 tmp[m++]=tmp[i-1]+1;
 86         sort(tmp,tmp+m);
 87         memset(tree,-1,sizeof(tree));
 88         for(i=0;i<n;i++)
 89         {
 90             int a=bin(li[i],m);
 91             int b=bin(ri[i],m);
 92             update(a,b,i,0,m,1);
 93         }
 94         memset(hash,0,sizeof(hash));
 95         ans=0;
 96         query(0,m,1);
 97         printf("%d\n",ans);
 98     }
 99     return 0;
100 }
View Code
原文地址:https://www.cnblogs.com/frog112111/p/3099341.html