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 }
  • 相关阅读:
    oracle的wm_concat()方法与的排序问题,Oracle的 listagg 函数
    sql sever 常用的存储过程的写法或者说与Oracle中存过的异同点
    Oracle游标的使用
    oracle与sql sever的财务月份归属的问题
    sql sever使用习惯
    sqlsever 的存储过程的调试
    sql sever与Oracle的异同点
    单例模式
    线程 ---- 锁(生产者、消费者)
    IO 流理解实例
  • 原文地址:https://www.cnblogs.com/kane0526/p/3048274.html
Copyright © 2011-2022 走看看