zoukankan      html  css  js  c++  java
  • 线段树专辑——pku 2528 Mayor's posters

    http://poj.org/problem?id=2528

    又是一道区间染色问题,经典问题,自然有经典解法:为线段树添加一个cover域,当cover的值为-1的时候,则说明该区间是有多种颜色组成的。当cover为一个非-1的值时,说明该区间为cover一种颜色组成。更新的时候只需要将单色的区间信息向下传递即可

    这题唯一要做的,或许就是离散化吧。离散化就是利用数组的下标与其值一一对应的映射关系的一种hash。

    View Code
      1 #include<iostream>
    2 #include<string>
    3 #include<algorithm>
    4 using namespace std;
    5
    6 struct node
    7 {
    8 int l;
    9 int r;
    10 int cover;
    11 };
    12
    13 node tree[100000];
    14 long xx[20001];
    15 int len,n;
    16
    17 struct post
    18 {
    19 long l;
    20 long r;
    21 };
    22
    23 post num[10001];
    24
    25 int find(long x) //二分查找某一个X在数组中对应的下标
    26 {
    27 int l=0,r=len,mid;
    28 while(l<=r)
    29 {
    30 mid=(l+r)>>1;
    31 if(xx[mid]==x)
    32 return mid;
    33 if(xx[mid]<x)
    34 l=mid+1;
    35 else
    36 r=mid-1;
    37 }
    38 return l;
    39 }
    40
    41 void build(int i,int l,int r)
    42 {
    43 tree[i].l=l;
    44 tree[i].r=r;
    45 tree[i].cover=0;
    46 if(l==r)
    47 return;
    48 int mid=(l+r)>>1;
    49 build(i<<1,l,mid);
    50 build(i<<1|1,mid+1,r);
    51 }
    52
    53 void updata(int i,int l,int r,int w)
    54 {
    55 if(tree[i].l>r || tree[i].r<l)
    56 return;
    57 if(tree[i].l>=l && tree[i].r<=r)
    58 {
    59 tree[i].cover=w;
    60 return;
    61 }
    62 if(tree[i].cover!=-1) //线段是单色的,那么向下传递
    63 {
    64 tree[i<<1].cover=tree[i<<1|1].cover=tree[i].cover;
    65 tree[i].cover=-1; //传递过后,将其标记为混色
    66 }
    67 updata(i<<1,l,r,w);
    68 updata(i<<1|1,l,r,w);
    69 }
    70
    71 int ans;
    72 int v[10001]; //用于标记重复的颜色统计
    73
    74 void query(int i)
    75 {
    76 if(tree[i].cover!=-1) //单色线段,记录它的颜色
    77 {
    78 if(!v[tree[i].cover])
    79 {
    80 v[tree[i].cover]=1;
    81 ans++;
    82 }
    83 return;
    84 }
    85 if(tree[i].l==tree[i].r)
    86 return;
    87 query(i<<1);
    88 query(i<<1|1);
    89 }
    90
    91 int main()
    92 {
    93 int cas,i,j;
    94 freopen("in.txt","r",stdin);
    95 scanf("%d",&cas);
    96 while(cas--)
    97 {
    98 scanf("%d",&n);
    99 j=0;
    100 for(i=0;i<n;i++)
    101 {
    102 scanf("%ld%ld",&num[i].l,&num[i].r);
    103 xx[j++]=num[i].l;
    104 xx[j++]=num[i].r;
    105 }
    106 sort(xx,xx+j);
    107 len=1;
    108 for(i=1;i<j;i++) //取消重复的数
    109 {
    110 if(xx[i-1]!=xx[i])
    111 {
    112 xx[len++]=xx[i];
    113 }
    114 }
    115 len--;
    116 build(1,0,len);
    117 for(i=0;i<n;i++)
    118 {
    119 int a=find(num[i].l); //离散化后查找
    120 int b=find(num[i].r);
    121 updata(1,a,b,i+1);
    122 }
    123 ans=0;
    124 memset(v,0,sizeof(v));
    125 query(1);
    126 printf("%d\n",ans);
    127 }
    128 return 0;
    129 }



  • 相关阅读:
    文件的编码是一个怎样的机制
    MySQL——修改root密码的4种方法(以windows为例)
    python中nltk的下载安装方式
    VNC轻松连接远程Linux桌面
    Linux 查看磁盘分区、文件系统、磁盘的使用情况相关的命令和工具介绍
    shell脚本中>/dev/null的含义
    执行shell脚本时提示bad interpreter:No such file or directory的解决办法
    TabLayout+ViewPager的简单使用
    让listView gridView全部扩展开
    购物车中的观察者模式的应用
  • 原文地址:https://www.cnblogs.com/ka200812/p/2244501.html
Copyright © 2011-2022 走看看