zoukankan      html  css  js  c++  java
  • poj2528Mayor's posters

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

    区间覆盖。

    离散化(有点特殊的离散化)。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define lson l,m,rt<<1
     5 #define rson m+1,r,rt<<1|1
     6 using namespace std;
     7 
     8 const int maxn=11111;
     9 int cnt;
    10 int f[maxn<<4];
    11 int li[maxn],ri[maxn];
    12 int has[maxn],X[maxn<<3];
    13 
    14 void pushdown(int rt)
    15 {
    16     if(f[rt]!=-1)
    17     {
    18         f[rt<<1]=f[rt<<1|1]=f[rt];
    19         f[rt]=-1;
    20     }
    21 }
    22 
    23 void update(int L,int R,int c,int l,int r,int rt)
    24 {
    25     if(L<=l&&r<=R)
    26     {
    27         f[rt]=c;
    28         return ;
    29     }
    30     int m=(l+r)>>1;
    31     pushdown(rt);
    32     if(L<=m) update(L,R,c,lson);
    33     if(m<R) update(L,R,c,rson);
    34 }
    35 void query(int l,int r,int rt)
    36 {
    37     if(f[rt]!=-1)
    38     {
    39         if(!has[f[rt]]) cnt++;
    40         has[f[rt]]=1;
    41         return;
    42     }
    43     if(l==r) return;
    44     int m=(l+r)>>1;
    45     query(lson);
    46     query(rson);
    47 }
    48 int bin(int x,int n,int X[])
    49 {
    50     int l=0,r=n-1;
    51     while(l<=r){
    52     int m=(l+r)>>1;
    53     if(X[m]==x) return m;
    54     if(X[m]>x) r=m-1;
    55     else l=m+1;
    56     }
    57     return -1;
    58 }
    59 int main()
    60 {
    61     int t;
    62     scanf("%d",&t);
    63     while(t--)
    64     {
    65         int n;
    66         scanf("%d",&n);
    67         int nn=0;
    68         for(int i=0;i<n;i++){
    69             scanf("%d%d",&li[i],&ri[i]);
    70             X[nn++]=li[i];
    71             X[nn++]=ri[i];
    72         }
    73         sort(X,X+nn);
    74         int m=1;
    75         for(int i=1;i<nn;i++)
    76         {
    77             if(X[i]!=X[i-1]) X[m++]=X[i];
    78         }
    79         for(int i=m-1;i>0;i--)
    80         {
    81             if(X[i]!=X[i-1]+1) X[m++]=X[i-1]+1;
    82         }
    83         sort(X,X+m);
    84         memset(f,-1,sizeof(f));
    85         for(int i=0;i<n;i++)
    86         {
    87             int L=bin(li[i],m,X);
    88             int R=bin(ri[i],m,X);
    89             update(L,R,i,0,m,1);
    90         }
    91         memset(has,0,sizeof(has));
    92         cnt=0;
    93         query(0,m,1);
    94         printf("%d
    ",cnt);
    95     }
    96     return 0;
    97 }
    不好

    很久之前做的一道题,一直有些地方很纠结。。。

    今天在hiho上看到了,用上面那种离散化竟然错了。。。

    学习了新姿势。。。

    想起来之前在哪看的一句话,人家三天就能学到线段树的精髓,你几个月还学得稀里糊涂。。大概说的就是我了。。。

    题目链接:hiho1079

    在线段树的通常用法中,线段树的节点是有2种不同的意义的,一种是离散型的,比如在Hiho一下 第二十周中,一个节点虽然描述的是一个区间[3, 9],但是实际上这样一个区间是{3, 4, 5, 6, 7, 8, 9}这样的意义。而另一种就是连续型的,比如就在这一周的问题中,一个节点如果描述的是一个区间[3, 9],它就确确实实描述的是在数轴上从3这个标记到9这个标记的这一段。

    这两种不同的意义有什么区别呢?

    在小Hi看来,其实只有这样的几个区别:1.叶子节点:在离散型中,叶子节点是[i, i],而连续性中是[i, i + 1];2.分解区间:在离散型中,一段区间是分解成为[l, m], [m + 1, r],而在连续型中,是分解成为[l, m], [m, r];3.其他所有类似的判定问题。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=100010;
     7 int f[maxn<<4];
     8 #define lson l,m,rt<<1
     9 #define rson m,r,rt<<1|1
    10 int li[maxn],ri[maxn];
    11 int X[maxn<<3];
    12 int has[maxn];
    13 int n,lo;
    14 int ct=0;
    15 int ans=0;
    16 
    17 
    18 void pushdown(int rt)
    19 {
    20     if(f[rt]!=-1)
    21     {
    22         f[rt<<1|1]=f[rt<<1]=f[rt];
    23         f[rt]=-1;
    24     }
    25 }
    26 
    27 void update(int L,int R,int id,int l,int r,int rt)
    28 {
    29     if(L<=l&&r<=R)
    30     {
    31         f[rt]=id;
    32         return;
    33     }
    34     int m=(l+r)>>1;
    35     pushdown(rt);
    36     if(L<m) update(L,R,id,lson);  //连续
    37     if(R>m) update(L,R,id,rson);
    38 }
    39 void query(int l,int r,int rt)
    40 {
    41     if(f[rt]!=-1)
    42     {
    43         if(!has[f[rt]]) ans++;
    44         has[f[rt]]=1;
    45         return;
    46     }
    47     if(l+1==r) return;  //连续区间的返回条件
    48     int m=(l+r)>>1;
    49     query(lson);
    50     query(rson);
    51 }
    52 
    53 int Bin(int x,int len,int *X)
    54 {
    55     int l=0,r=len;
    56     while(l<=r)
    57     {
    58         int m=(l+r)>>1;
    59         if(X[m]==x) return m;
    60         if(X[m]>x) r=m-1;
    61         else l=m+1;
    62     }
    63     return -1;
    64 }
    65 int main()
    66 {
    67     scanf("%d%d",&n,&lo);
    68     for(int i=0;i<n;i++)
    69     {
    70         scanf("%d%d",&li[i],&ri[i]);
    71         X[ct++]=li[i];
    72         X[ct++]=ri[i];
    73     }
    74     sort(X,X+ct);
    75     int m=1;
    76     for(int i=1;i<ct;i++) if(X[i]!=X[i-1]) X[m++]=X[i];  //离散化
    77     m--;
    78     memset(f,-1,sizeof(f));
    79     for(int i=0;i<n;i++)
    80     {
    81         int L=Bin(li[i],m,X);
    82         int R=Bin(ri[i],m,X);
    83         update(L,R,i,0,m,1);
    84     }
    85     memset(has,0,sizeof(has));
    86     query(0,m,1);
    87     printf("%d
    ",ans);
    88 }
    参考


     再次更新。。。

    是读题读错了ozr,题目说的线段并不是线段,它是用一个编号表示一个线段,所以本质上当成点做就可以了。。。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=100010;
     7 int f[maxn<<4];
     8 #define lson l,m,rt<<1
     9 #define rson m+1,r,rt<<1|1
    10 int li[maxn],ri[maxn];
    11 int X[maxn<<3];
    12 int has[maxn];
    13 int n,lo;
    14 int ct=0;
    15 int ans=0;
    16 
    17 
    18 void pushdown(int rt)
    19 {
    20     if(f[rt]!=-1)
    21     {
    22         f[rt<<1|1]=f[rt<<1]=f[rt];
    23         f[rt]=-1;
    24     }
    25 }
    26 
    27 void update(int L,int R,int id,int l,int r,int rt)
    28 {
    29     if(L<=l&&r<=R)
    30     {
    31         f[rt]=id;
    32         return;
    33     }
    34     int m=(l+r)>>1;
    35     pushdown(rt);
    36     if(L<=m) update(L,R,id,lson);  //连续
    37     if(R>m) update(L,R,id,rson);
    38 }
    39 void query(int l,int r,int rt)
    40 {
    41     if(f[rt]!=-1)
    42     {
    43         if(!has[f[rt]]) ans++;
    44         has[f[rt]]=1;
    45         return;
    46     }
    47     if(l==r) return;  //连续区间的返回条件
    48     int m=(l+r)>>1;
    49     query(lson);
    50     query(rson);
    51 }
    52 
    53 int Bin(int x,int len,int *X)
    54 {
    55     int l=0,r=len;
    56     while(l<=r)
    57     {
    58         int m=(l+r)>>1;
    59         if(X[m]==x) return m;
    60         if(X[m]>x) r=m-1;
    61         else l=m+1;
    62     }
    63     return -1;
    64 }
    65 int main()
    66 {
    67     int t;
    68     scanf("%d",&t);
    69     while(t--){
    70     scanf("%d",&n);
    71     for(int i=0;i<n;i++)
    72     {
    73         scanf("%d%d",&li[i],&ri[i]);
    74         X[ct++]=li[i];
    75         X[ct++]=ri[i];
    76     }
    77     sort(X,X+ct);
    78     int m=1;
    79     for(int i=1;i<ct;i++) if(X[i]!=X[i-1]) X[m++]=X[i];  //离散化
    80     m--;
    81     memset(f,-1,sizeof(f));
    82     for(int i=0;i<n;i++)
    83     {
    84         int L=Bin(li[i],m,X);
    85         int R=Bin(ri[i],m,X);
    86         update(L,R,i,0,m,1);
    87     }
    88     memset(has,0,sizeof(has));
    89     ans=0;
    90     query(0,m,1);
    91     printf("%d
    ",ans);
    92     }
    93 }
    View Code
  • 相关阅读:
    吴裕雄--天生自然 python数据分析:加纳卫生设施数据分析
    吴裕雄--天生自然 python开发学习笔记:一劳永逸解决绘图出现中文乱码问题方法
    吴裕雄--天生自然 python开发学习笔记:pycharm无法使用ctrl+c/v复制粘贴的问题
    吴裕雄--天生自然 Tensorflow卷积神经网络:花朵图片识别
    吴裕雄--天生自然 PHP开发学习:在centos7操作系统下使用命令安装ThinkPHP 5框架
    克拉克拉(KilaKila):大规模实时计算平台架构实战
    专访阿里云MVP黄胜蓝:90 后 CTO花了6年,改变了你日常生活里的这件事
    专访阿里云MVP王俊杰:开发者的超能力是用技术让世界更美好
    深入解读阿里云数据库POLARDB核心功能会话读一致性
    阿里开发者们的第15个感悟:做一款优秀大数据引擎,要找准重点解决的业务场景
  • 原文地址:https://www.cnblogs.com/yijiull/p/6619154.html
Copyright © 2011-2022 走看看