• hdu 4614 Vases and Flowers(线段树加二分查找)


    周赛题

      1 /*
      2 线段树+二分查找
      3 处理比较麻烦,关键在用二分查找配合query()操作找从左往右第一个0和从右往左第一个0
      4 
      5 卡到的地方:
      6 1、区间更新不熟练
      7 2、关键点没想到
      8 3、低级错误位运算<<写成>>
      9 */
     10 #include <cstdio>
     11 #include <cstring>
     12 #define N 50005
     13 #define lson l,m,rt<<1
     14 #define rson m+1,r,rt<<1|1
     15 
     16 int emp[N<<2]; //0-区间下全为0,1-区间下全为1, 2-区间下不纯
     17 
     18 void build(int l, int r, int rt)
     19 {
     20     emp[rt] = 0;
     21     if(l==r) return;
     22     int m = (l + r) >> 1;
     23     build(lson);
     24     build(rson);
     25 }
     26 
     27 //s: 置0-空瓶 置1-摆花
     28 void update(int s, int a, int b, int l, int r, int rt)
     29 {
     30     int m = (l + r) >> 1;
     31     //不在范围内,不更新
     32     if(l>b || r<a) return;
     33     if(emp[rt]==s) return;
     34     if(emp[rt]==2)
     35     {
     36         if(a<=l && r<=b)
     37         {
     38             emp[rt] = s;
     39             return ;
     40         }
     41         update(s,a,b,lson);
     42         update(s,a,b,rson);
     43     }
     44     else
     45     {
     46         if(a<=l && r<=b)
     47         {
     48             emp[rt] = s;
     49             return ;
     50         }
     51         emp[rt<<1] = emp[rt];
     52         emp[rt<<1|1] = emp[rt];
     53         emp[rt] = 2;
     54         update(s,a,b,lson);
     55         update(s,a,b,rson);
     56     }
     57 }
     58 
     59 //查询a-b有多少个s(0或1)
     60 int query(int s, int a, int b, int l, int r, int rt)
     61 {
     62     if(l>b || r<a) return 0;
     63     int m = (l + r) >> 1;
     64     if(emp[rt]==s)
     65     {
     66         if(a<=l && r<=b)
     67             return r - l + 1;
     68         emp[rt<<1] = emp[rt];
     69         emp[rt<<1|1] = emp[rt];
     70         return query(s, a, b, lson) + query(s, a, b, rson);
     71     }
     72     else if(emp[rt]==2)
     73     {
     74         return query(s, a, b, lson) + query(s, a, b, rson);
     75     }
     76     else
     77         return 0;
     78 
     79 }
     80 
     81 //a-b从左往右找第一个0
     82 int bs(int a, int b, int num, int n)
     83 {
     84     int l = a, r = b, m;
     85     while(l<=r)
     86     {
     87         m = (l + r) / 2;
     88         int tmp = query(0, a, m, 1, n, 1);
     89         //printf("Loop-m:%d tmp:%d ",m,tmp);
     90         if(tmp==num && query(0,m,m,1,n,1)==1return m;
     91         else if(tmp<num) l = m + 1;
     92         else r = m - 1;
     93     }
     94     return l;
     95 }
     96 
     97 //a-b中右到左找第一个0
     98 int bsright(int a, int b, int n)
     99 {
    100     int l = a, r = b, m;
    101     while(l<=r)
    102     {
    103         m = (l + r) / 2;
    104         int tmp = query(0, m, b, 1, n, 1);
    105         //printf("Loop-m:%d tmp:%d ",m,tmp);
    106         if(tmp==1 && query(0,m,m,1,n,1)==1return m;
    107         else if(tmp<1) r = m - 1;
    108         else l = m + 1;
    109     }
    110     return r;
    111 }
    112 
    113 int main()
    114 {
    115     int t, n, m, a, b, k;
    116     scanf("%d",&t);
    117     while(t--)
    118     {
    119         scanf("%d%d",&n,&m);
    120         build(1,n,1);
    121         while(m--)
    122         {
    123             scanf("%d%d%d",&k,&a,&b);
    124             if(k==2)
    125             {
    126                 a++; b++;
    127                 printf("%d ",query(1,a,b,1,n,1));
    128                 update(0,a,b,1,n,1);
    129 
    130             }
    131             else if(k==1)
    132             {
    133                 a++;
    134                 int tmp = query(0,a,n,1,n,1);
    135                 if(tmp==0)
    136                 {
    137                     printf("Can not put any one. ");
    138                 }
    139                 else if(tmp<b)
    140                 {
    141                     //printf("postmp:%d ",bs(a,n,tmp,n));
    142                     printf("%d %d ",bs(a,n,1,n)-1,bsright(a,n,n)-1);
    143                     update(1,a,n,1,n,1);
    144                 }
    145                 else
    146                 {
    147                     int bb = bs(a,n,b,n);
    148                     printf("%d %d ",bs(a,n,1,n)-1,bsright(a,bb,n)-1);
    149                     update(1,a,bb,1,n,1);
    150                 }
    151 
    152             }
    153         }
    154         printf(" ");
    155     }
    156     return 0;
    157 }
  • 相关阅读:
    Application的使用(使用,及要注意的内存泄露问题)
    ANDROID 2.3 HOTPLUG input设备event处理以及hotplug检测
    博客园随笔添加自己的版权信息
    还贷的那些事III——等额还贷的计算
    计算机中的颜色IX——总述:RGB和HSV快速转换
    还贷的那些事II——等本还贷的计算
    计算机中的颜色VII——快速计算纯色的偏转
    还贷的那些事I——还贷的基本概念
    计算机中的颜色VIII——快速计算颜色的偏转
    计算字符串的相似度(VB2005)
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3631362.html
Copyright © 2020-2023  润新知