POJ 2528 Mayor's posters

第一次学会离散化,是在B站看qsc的视频学会的新姿势,特别好写啊,而且效率也不差, 只需要两行代码  

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <algorithm>
  4 #include <string.h>
  5 #include <vector>
  6 #define ls (pos<<1)
  7 #define rs (pos<<1|1)
  8 const int MAXN=3e5+10;
  9 int ans;
 10 int cov[MAXN];  //记录没被覆盖的颜色的种类数 能看到为1,看不到用0表示
 11 using namespace std;
 12 struct node
 13 {
 14     int l,r;
 15     int c; //当前节点代表的区间颜色&&懒惰标记
 16     int mid()
 17     {
 18         return (l+r)>>1;
 19     }
 20 }a[MAXN<<2];
 21 struct post
 22 {
 23     int l,r;
 24 }p[MAXN];
 25 vector<int> b;
 26 void build(int l,int r,int pos)
 27 {
 28     a[pos].l=l;
 29     a[pos].r=r;
 30     a[pos].c=-1;
 31     if(l==r)
 32         return;
 33     int mid=a[pos].mid();
 34     build(l,mid,ls);
 35     build(mid+1,r,rs);
 36 }
 37 //下推懒惰标记
 38 void pushdown(int pos)
 39 {
 40     if(a[pos].c!=-1)
 41     {
 42         if(a[pos].l==a[pos].r)
 43         {
 44             a[pos].c=-1;
 45             return;
 46         }
 47         //将当前节点的颜色下推到子节点
 48         a[ls].c=a[pos].c;
 49         a[rs].c=a[pos].c;
 50         a[pos].c=-1;   //下推后当前结点的标记要清零
 51     }
 52 }
 53 void update(int l,int r,int c,int pos)
 54 {
 55     //当前结点表示的区间在[l,r]内,直接更新当前区间的颜色
 56     if(l<=a[pos].l&&a[pos].r<=r)
 57     {
 58         a[pos].c=c;
 59         return ;
 60     }
 61     //下退标记
 62     pushdown(pos);
 63     int mid=a[pos].mid();
 64     if(r<=mid) update(l,r,c,ls);
 65     else if(l>mid) update(l,r,c,rs);
 66     else
 67     {
 68         update(l,mid,c,ls);
 69         update(mid+1,r,c,rs);
 70     }
 71 }
 72 void query(int l,int r,int pos)
 73 {
 74     if(a[pos].c!=-1)
 75     {
 76         if(!cov[a[pos].c])
 77         {
 78             cov[a[pos].c]=1;
 79             ans++;
 80         }
 81         return ;
 82     }
 83     pushdown(pos);
 84     if(l==r) return ;
 85     query(l,a[pos].mid(),ls);
 86     query(a[pos].mid()+1,r,rs);
 87 }
 88 int main()
 89 {
 90     int n,t,x,y,c;
 91     scanf("%d",&t);
 92     while(t--)
 93     {
 94         b.clear();
 95         vector<int> c;
 96         scanf("%d",&n);
 97         for(int i=1;i<=n;i++)
 98         {
 99             scanf("%d %d",&p[i].l,&p[i].r);
100             b.push_back(p[i].l);
101             b.push_back(p[i].r);
102         }
103         //离散化
104         sort(b.begin(),b.end());
105         b.erase(unique(b.begin(),b.end()),b.end());
106         //在差值大于二的数中间插入一个数字b[i]-1
107         c.push_back(b[0]);
108         for(int i=0;i<b.size();i++)
109         {
110             if(b[i]-b[i-1]>1) c.push_back(b[i]-1);
111             c.push_back(b[i]);
112         }
113         build(1,(int)b.size(),1);
114         //模拟张贴海报(涂颜色)
115         for(int i=1;i<=n;i++)
116         {
117             x=lower_bound(b.begin(),b.end(),p[i].l)-b.begin()+1;
118             y=lower_bound(b.begin(),b.end(),p[i].r)-b.begin()+1;
119             update(x,y,i,1);
120         }
121         ans=0;
122         memset(cov,0,sizeof(cov));
123         query(1,b.size(),1);
124         printf("%d\n",ans);
125     }
126     return 0;
127 }

 

posted @ 2018-04-20 14:15  WOOOOO  阅读(145)  评论(0编辑  收藏  举报