zoukankan      html  css  js  c++  java
  • HDU 4614 Vases and Flowers 线段树 + 二分

    线段树节点记录内容请见代码注释

    操作1:每次查询区间 [A, N - 1] 中第一个空格的位置,然后在[ A, N - 1 ]中二分右端点的位置。实际放的花的数量是 要求数量 与 剩余空格数量 之间的最小值

    如果[ A, N - 1 ]中已经没有空格了,就不能放了。

    操作2:求和与成端更新,线段树基本操作不解释

    比赛的时候把PushDown函数写错了,样例死活不过,比赛结束之后才看出来,2A之,orz……要不要这么伤人……

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 
      6 #define lson l, m, rt << 1
      7 #define rson m + 1, r, rt << 1 | 1
      8 
      9 using namespace std;
     10 
     11 const int MAXN = 50010;
     12 const int INF = 1 << 30;
     13 
     14 int N, Q, ok;
     15 int flag[ MAXN << 2 ];    //无标记:-1,清空:0,占用:1
     16 int sum[ MAXN << 2 ];     //区间占用区域总和
     17 int len[ MAXN << 2 ];     //空闲区域长度总和
     18 int addr[ MAXN << 2 ];    //本区间第一个空格的位置
     19 
     20 void PushUp( int rt, int l, int r )
     21 {
     22     int lc = rt << 1;
     23     int rc = rt << 1 | 1;
     24     sum[rt] = sum[lc] + sum[rc];
     25     len[rt] = len[lc] + len[rc];
     26     addr[rt] = min( addr[lc], addr[rc] );
     27 
     28     return;
     29 }
     30 void PushDown( int rt, int l, int r )
     31 {
     32     int m = ( l + r ) >> 1;
     33     int lc = rt << 1;
     34     int rc = rt << 1 | 1;
     35     if ( flag[rt] != -1 )
     36     {
     37         flag[lc] = flag[rc] = flag[rt];
     38         if ( flag[rt] == 1 )   //如果占用
     39         {
     40             sum[lc] = m - l + 1;
     41             sum[rc] = r - m;
     42             len[lc] = len[rc] = 0;
     43             addr[lc] = addr[rc] = INF;   //本区间没有空格
     44         }
     45         else
     46         {
     47             sum[lc] = sum[rc] = 0;
     48             len[lc] = m - l + 1;
     49             len[rc] = r - m;
     50             addr[lc] = l;
     51             addr[rc] = m + 1;
     52         }
     53         flag[rt] = -1;
     54     }
     55     return;
     56 }
     57 void build( int l, int r, int rt )
     58 {
     59     flag[rt] = -1;
     60     if ( l == r )
     61     {
     62         sum[rt] = 0;
     63         len[rt] = r - l + 1;
     64         addr[rt] = l;
     65         return;
     66     }
     67     int m = ( l + r ) >> 1;
     68     build( lson );
     69     build( rson );
     70     PushUp( rt, l, r );
     71     return;
     72 }
     73 
     74 int QuerySum( int L, int R, int l, int r, int rt )
     75 {
     76     //printf( "preS: [%d, %d]: sum = %d
    ", l, r, sum[rt] );
     77     if ( L <= l && r <= R ) return sum[rt];
     78     PushDown( rt, l, r );
     79 
     80     int m = ( l + r ) >> 1;
     81     int res = 0;
     82 
     83     if ( L <= m ) res += QuerySum( L, R, lson );
     84     if ( R > m )  res += QuerySum( L, R, rson );
     85     PushUp( rt, l, r );
     86 
     87     //printf( "afterS: [%d, %d]: sum = %d
    ", l, r, sum[rt] );
     88     return res;
     89 }
     90 
     91 //查询大于等于st的第一个空格的位置
     92 int QueryConti( int L, int R, int l, int r, int rt )
     93 {
     94     if ( L <= l && r <= R )
     95     {
     96         return addr[rt];
     97     }
     98     PushDown( rt, l, r );
     99     int m = ( l + r ) >> 1;
    100     int tmp = INF;
    101 
    102     if ( L <= m ) tmp = min( tmp, QueryConti( L, R, lson ) );
    103     if ( R > m )  tmp = min( tmp, QueryConti( L, R, rson ) );
    104 
    105     PushUp( rt, l, r );
    106 
    107     return tmp;
    108 }
    109 
    110 void Update( int L, int R, int c, int l, int r, int rt )
    111 {
    112     //printf( "pre UP [%d, %d]: sum = %d
    ", l, r, sum[rt] );
    113     if ( L <= l && r <= R )
    114     {
    115         flag[rt] = c;
    116         if ( flag[rt] == 1 )   //如果占用
    117         {
    118             sum[rt] = r - l + 1;
    119             len[rt] = 0;
    120             addr[rt] = INF;   //本区间没有空格
    121         }
    122         else
    123         {
    124             sum[rt] = 0;
    125             len[rt] = r - l + 1;
    126             addr[rt] = l;
    127         }
    128         return;
    129     }
    130     PushDown( rt, l, r );
    131 
    132     int m = ( l + r ) >> 1;
    133     if ( L <= m ) Update( L, R, c, lson );
    134     if ( R > m )  Update( L, R, c, rson );
    135     PushUp( rt, l, r );
    136 
    137     //printf( "after UP [%d, %d]: sum = %d
    ", l, r, sum[rt] );
    138     return;
    139 }
    140 
    141 int BiSearch( int l, int r, int st, int tar )
    142 {
    143     //printf("tar=%d
    ", tar);
    144     while ( l <= r )
    145     {
    146         int mid = ( l + r ) >> 1;
    147         int sum = QuerySum( st, mid, 0, N - 1, 1 );
    148         sum = mid - st + 1 - sum;
    149         if ( sum >= tar ) r = mid;
    150         else l = mid + 1;
    151         if ( l == r ) return l;
    152     }
    153     return l;
    154 }
    155 
    156 int main()
    157 {
    158     //freopen( "s.out", "w", stdout );
    159     int T;
    160     scanf( "%d", &T );
    161     while( T-- )
    162     {
    163         scanf( "%d%d", &N, &Q );
    164         build( 0, N - 1, 1 );
    165         while ( Q-- )
    166         {
    167             int op, a, b;
    168             scanf( "%d%d%d", &op, &a, &b );
    169             if ( op == 1 )
    170             {
    171                 if ( b == 0 ) continue;
    172                 int ans = QuerySum( a, N - 1, 0, N - 1, 1 );
    173                 if ( ans == N - a )
    174                     puts("Can not put any one.");
    175                 else
    176                 {
    177                     //printf( "%d %d
    ", N - a, ans );
    178                     int FF = min( N - a - ans, b );
    179                     int left = QueryConti( a, N - 1, 0, N - 1, 1 );
    180                     int right = BiSearch( a, N - 1, a, FF );
    181                     printf( "%d %d
    ", left, right );
    182                     Update( left, right, 1, 0, N - 1, 1 );
    183                 }
    184             }
    185             else
    186             {
    187                 int ans = QuerySum( a, b, 0, N - 1, 1 );
    188                 printf( "%d
    ", ans );
    189                 Update( a, b, 0, 0, N - 1, 1 );
    190             }
    191             //puts("**********");
    192         }
    193         puts("");
    194     }
    195     return 0;
    196 }
  • 相关阅读:
    TMS 例子63 分组,子node
    读写注册表 registrykey 创建删除
    如何打开 系统信息窗体和 DirectX诊断工具
    Socket 类通信例子-第24章
    判断IP地址是否合法类
    MySQL存储过程与存储函数的区别
    电脑设定自动开关机,并记录开关机时间
    WPS 表格筛选两列相同数据-完美-2017年11月1日更新
    通过TStringList保存csv文件,只要循环.Add表格里面的每行记录进去,保存即可
    Delphi中滚动文字的应用
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3214782.html
Copyright © 2011-2022 走看看