zoukankan      html  css  js  c++  java
  • 【HDU1199】 离散化线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1199

    题目大意: 一段长度未知的线段,一种操作:a b c ,表示区间[a,b]要涂的颜色,c=w涂白色,c=b涂黑色,问你最长的白色区间段时多长。

    解题思路:

                就快去南京邀请赛了,最近做题超没状态,CF rating一直掉,这么简单的线段树离散化居然搞了我一个晚上,纠结。

                开始用线段树区间合并的方法做,WA到死,换个写法,又WA到死,没处理好边界问题。

                这题用普通的离散化没用,藐视这种离散化第一次遇见,以前的离散化要么就是点化点,线段化点,这题不一样,是点化线段,一不小心处理不好就WA了。

    点化线段我利用的是左闭右开,即对于一段区间[a,b],转化成区间[a,b+1),接下来就是把所有端点当做简单的离散化处理了,然后运用线段树成段更新操作处理就好了。

    View Code
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 #define lz 2*u,l,mid
      8 #define rz 2*u+1,mid,r   ///注意:这里是点化为线段(左闭右开)
      9 const int maxn=5555;
     10 const int oo=0x3fffffff;
     11 int flag[4*maxn], color[maxn];
     12 int X[maxn];
     13 
     14 struct Node
     15 {
     16     int lx, rx, s;
     17     Node(){}
     18     Node(int lx_, int rx_, int s_)
     19     {
     20         lx=lx_, rx=rx_, s=s_;
     21     }
     22 }line[maxn];
     23 
     24 void push_down(int u, int l, int r)
     25 {
     26     if(flag[u]==-1) return ;
     27     else
     28     {
     29         flag[2*u]=flag[2*u+1]=flag[u];
     30         flag[u]=-1;
     31     }
     32 }
     33 
     34 void Update(int u, int l, int r, int tl, int tr, int c)
     35 {
     36     if(tl>=tr) return ; ///这里要注意了
     37     if(tl<=l&&r<=tr)
     38     {
     39         flag[u]=c;
     40         return ;
     41     }
     42     push_down(u,l,r);
     43     int mid=(l+r)>>1;
     44     if(tr<=mid) Update(lz,tl,tr,c);
     45     else if(tl>mid) Update(rz,tl,tr,c);
     46     else
     47     {
     48         Update(lz,tl,mid,c);
     49         Update(rz,mid,tr,c);
     50     }
     51 }
     52 
     53 void Query(int u, int l, int r)
     54 {
     55     if(l>=r) return ; ///!!!
     56     if(flag[u]!=-1)
     57     {
     58         for(int i=l; i<r; i++) color[i]=flag[u];  ///右端点不标记
     59         return ;
     60     }
     61     push_down(u,l,r);
     62     int mid=(l+r)>>1;
     63     Query(lz);
     64     Query(rz);
     65 }
     66 
     67 int find(int tmp, int n)
     68 {
     69     int l=1, r=n, mid;
     70     while(l<=r)
     71     {
     72         mid=(l+r)>>1;
     73         if(X[mid]==tmp) return mid;
     74         else if(X[mid]<tmp) l=mid+1;
     75         else r=mid-1;
     76     }
     77 }
     78 
     79 int main()
     80 {
     81     int n, x, y, c;
     82     char ch[3];
     83     while(~scanf("%d",&n))
     84     {
     85         int num=0;
     86         for(int i=0; i<n; i++)
     87         {
     88             scanf("%d%d%s",&x,&y,ch);
     89             if(*ch=='w') c=1;
     90             else c=0;
     91             line[i]=Node(x,y+1,c);
     92             X[++num]=x;
     93             X[++num]=y+1;
     94         }
     95         sort(X+1,X+num+1);
     96         int ep=1;
     97         for(int i=2; i<=num; i++)
     98             if(X[ep]!=X[i]) X[++ep]=X[i];
     99         memset(color,0,sizeof(color));
    100         memset(flag,-1,sizeof(flag));
    101         for(int i=0; i<n; i++)
    102         {
    103             int lx=find(line[i].lx,ep);
    104             int rx=find(line[i].rx,ep);
    105             Update(1,1,ep+1,lx,rx,line[i].s);
    106         }
    107         Query(1,1,ep+1);
    108         int s=0, d=0, ts, td;
    109         for(int i=1; i<=ep; i++)
    110         {
    111               if(color[i]!=1) continue;
    112               ts=X[i];
    113               while(color[i]==1) i++;
    114               if(i>ep) break;
    115               td=X[i];
    116               if(td-ts>d-s)
    117               {
    118                   s=ts;
    119                   d=td;
    120               }
    121         }
    122         if(s==d) puts("Oh, my god");
    123         else printf("%d %d\n",s, d-1);
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    JS中使用正则表达式封装的一些常用的格式验证的方法-是否外部url、是否小写、邮箱格式、是否字符、是否数组
    Java中操作字符串的工具类-判空、截取、格式化、转换驼峰、转集合和list、是否包含
    Cocos2d-x 2.0 自适应多种分辨率
    应用自定义移动设备外观
    为移动设备应用程序创建外观
    【2020-11-28】人生十三信条
    【2020-11-27】事实证明,逃避是下等策略
    Python 之web动态服务器
    Python 之pygame飞机游戏
    PHP 之转换excel表格中的经纬度
  • 原文地址:https://www.cnblogs.com/kane0526/p/3048274.html
Copyright © 2011-2022 走看看