zoukankan      html  css  js  c++  java
  • hdu 1199 color the ball

    离散化时将左右节点 (l[i],r[i]) 和左节点减1 (l[i]-1) 全部加入,离散化

    建树时用段树方法比较方便,即叶子节点表示一个区间而不是一个值,很多边界问题就不用考虑了

    1 #include<cstdio>
    2 #include<cstring>
    3 #include<algorithm>
    4  using namespace std;
    5  #define M 6060
    6
    7  int dis[M],m;
    8 int Find(int x){
    9 int low=0,high=m;
    10 int mid=(low+high)>>1;
    11 while(true){
    12 if(dis[mid]==x){
    13 return mid;
    14 }else if(dis[mid]>x){
    15 high=mid-1;
    16 }else if(dis[mid]<x){
    17 low=mid+1;
    18 }
    19 mid=(low+high)>>1;
    20 }
    21 }
    22
    23 struct Seg_Tree{
    24 int left,right;
    25 int lm,rm,len,lp;
    26 bool col,flag;
    27 //left,right 左右值(离散)
    28 //lm,rm 表示该区间最左端和最右端的白色球区间的长度(非离散)
    29 //len 表示该区间的最大长度(非离散)
    30 //lp 表示该区间最大长度开始的位置(非离散)
    31 //col 表示该区间是否为白色
    32 //flag 传说中的lazy标记
    33 int Glen(){
    34 //该区间的总长度(非离散)
    35 return dis[right]-dis[left];
    36 }
    37 }STree[M<<2];
    38
    39 void Build(int left,int right,int idx){
    40 STree[idx].left=left;
    41 STree[idx].right=right;
    42 STree[idx].lm=0;
    43 STree[idx].rm=0;
    44 STree[idx].lp=dis[left];
    45 STree[idx].len=0;
    46 STree[idx].flag=false;
    47 STree[idx].col=false;
    48 //叶子节点是一个区间,处理长度时会方便很多
    49 //注意下面递归时范围的不同
    50 if(right-left==1) return;
    51 int mid=(left+right)>>1;
    52 Build(left,mid,idx<<1);
    53 Build(mid,right,idx<<1|1);
    54 }
    55
    56 void Update(int idx,bool val){
    57 STree[idx].col=val;
    58 STree[idx].flag=true;
    59 if(val) STree[idx].len=STree[idx].Glen();
    60 else STree[idx].len=0;
    61 STree[idx].lm=STree[idx].rm=STree[idx].len;
    62 STree[idx].lp=dis[STree[idx].left];
    63 }
    64
    65 void Modify(int left,int right,int idx,bool val){
    66 if(STree[idx].left==left&&STree[idx].right==right){
    67 Update(idx,val);
    68 return;
    69 }
    70
    71 if(STree[idx].flag){
    72 STree[idx].flag=false;
    73 Update(idx<<1,STree[idx].col);
    74 Update(idx<<1|1,STree[idx].col);
    75 }
    76
    77 int mid=(STree[idx].left+STree[idx].right)>>1;
    78 if(right<=mid){
    79 Modify(left,right,idx<<1,val);
    80 }else if(left>=mid){
    81 Modify(left,right,idx<<1|1,val);
    82 }else{
    83 Modify(left,mid,idx<<1,val);
    84 Modify(mid,right,idx<<1|1,val);
    85 }
    86
    87 if(STree[idx<<1].len>=STree[idx<<1|1].len){
    88 STree[idx].len=STree[idx<<1].len;
    89 STree[idx].lp=STree[idx<<1].lp;
    90 }else{
    91 STree[idx].len=STree[idx<<1|1].len;
    92 STree[idx].lp=STree[idx<<1|1].lp;
    93 }
    94 if(STree[idx<<1].rm+STree[idx<<1|1].lm>STree[idx].len){
    95 STree[idx].len=STree[idx<<1].rm+STree[idx<<1|1].lm;
    96 STree[idx].lp=dis[STree[idx<<1].right]-STree[idx<<1].rm;
    97 }
    98
    99 STree[idx].lm=STree[idx<<1].lm;
    100 if(STree[idx<<1].len==STree[idx<<1].Glen()){
    101 STree[idx].lm=STree[idx<<1].len+STree[idx<<1|1].lm;
    102 }
    103 STree[idx].rm=STree[idx<<1|1].rm;
    104 if(STree[idx<<1|1].len==STree[idx<<1|1].Glen()){
    105 STree[idx].rm=STree[idx<<1|1].len+STree[idx<<1].rm;
    106 }
    107 }
    108
    109 int l[2010],r[2010];
    110 bool c[2010];
    111 int main(){
    112 int n;
    113 while(~scanf("%d",&n)){
    114 for(int i=0;i<n;i++){
    115 char col[5];
    116 scanf("%d%d %s",&l[i],&r[i],col);
    117 if(col[0]=='w'){
    118 c[i]=true;
    119 }else if(col[0]=='b'){
    120 c[i]=false;
    121 }
    122 //l[i],r[i],l[i]-1 加入离散
    123 //将l[i]-1改为r[i]+1也可,但要注意数据范围
    124 dis[i*3]=l[i];
    125 dis[i*3+1]=r[i];
    126 dis[i*3+2]=l[i]-1;
    127 }
    128
    129 sort(dis,dis+n*3);
    130 m=0;
    131 for(int i=1;i<n*3;i++){
    132 if(dis[i]==dis[i-1]) continue;
    133 dis[++m]=dis[i];
    134 }
    135
    136 Build(0,m,1);
    137 for(int i=0;i<n;i++){
    138 //插入时将左值减1,全部转化为区间
    139 int ll=Find(l[i])-1;
    140 int rr=Find(r[i]);
    141 Modify(ll,rr,1,c[i]);
    142 }
    143 if(STree[1].len==0){
    144 puts("Oh, my god");
    145 }else{
    146 printf("%d %d\n",STree[1].lp+1,STree[1].lp+STree[1].len);
    147 }
    148 }
    149 }
  • 相关阅读:
    IOS基于 fmdb数据库 的简单操作应用
    App 上线被拒绝的原因有哪些?
    cocoaPods的安装以及使用
    IOS开发工程师的近期面试题
    UIButton基本介绍
    UIView 详解
    使用 Paros 抓接口
    如何在main方法中创建50000次对象
    如何将将String 转换 int
    2020年09月24号--测试登录账号15分钟有效时长
  • 原文地址:https://www.cnblogs.com/ambition/p/hdu1199.html
Copyright © 2011-2022 走看看