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

    题目链接

    比赛的时候一直想用树状数组,但是树状数组区间更新之后,功能有局限性。线段树中的lz标记很强大,这个题的题意也挺纠结的。

    k = 1时,从a开始,插b个花,输出第一个插的位置,最后一个的位置,一个都没插,输出不能插。

    k = 2时,将[a,b]区间都清空,输出这个区间上本来有多少朵花。

    主要是k = 1的时候,很难弄。给出区间[a,b]要找到第一个空花瓶,空花瓶的个数 = 总的-插花的个数

    这肯定是一个单增的,所以利用二分求下界,这个位置,就是第一个空花瓶的位置,最后一个花瓶的位置需要特判一下,确定是第几个空花瓶,剩下的跟算第一个差不多。

    主要是很多细节要注意,写代码要各种严谨....

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <cstdlib>
      6 using namespace std;
      7 #define lson l,m,rt<<1
      8 #define rson m+1,r,rt<<1|1
      9 int sum[4*50001];
     10 int lz[4*50001];
     11 int n;
     12 void pushup(int rt)
     13 {
     14     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     15 }
     16 void pushdown(int rt,int m)
     17 {
     18     if(lz[rt] == 1)
     19     {
     20         lz[rt<<1] = lz[rt];
     21         lz[rt<<1|1] = lz[rt];
     22         sum[rt<<1] = (m - (m>>1));
     23         sum[rt<<1|1] = (m>>1);
     24         lz[rt] = 0;
     25     }
     26     else if(lz[rt] == -1)
     27     {
     28         lz[rt<<1] = lz[rt];
     29         lz[rt<<1|1] = lz[rt];
     30         sum[rt<<1] = 0;
     31         sum[rt<<1|1] = 0;
     32         lz[rt] = 0;
     33     }
     34 }
     35 int query(int L,int R,int l,int r,int rt)
     36 {
     37     int m;
     38     int ans = 0;
     39     if(l >= L&&r <= R)
     40     {
     41         return sum[rt];
     42     }
     43     pushdown(rt,r-l+1);
     44     m = (l+r)>>1;
     45     if(L <= m) ans += query(L,R,lson);
     46     if(R > m) ans += query(L,R,rson);
     47     return ans;
     48 }
     49 void update(int L,int R,int sc,int l,int r,int rt)
     50 {
     51     int m;
     52     if(l >= L&&r <= R)
     53     {
     54         lz[rt] = sc;
     55         if(sc == 1)
     56         sum[rt] = (r - l + 1);
     57         else
     58         sum[rt] = 0;
     59         return ;
     60     }
     61     pushdown(rt,r-l+1);
     62     m = (l+r) >> 1;
     63     if(L <= m) update(L,R,sc,lson);
     64     if(R > m) update(L,R,sc,rson);
     65     pushup(rt);
     66 }
     67 int bis(int x,int key)
     68 {
     69     int str,end,mid,temp;
     70     str = x,end = n-1;
     71     if(end-x+1 - query(x,end,0,n-1,1) == 0)
     72     return -1;
     73     while(str < end)
     74     {
     75         mid = (str + end)/2;
     76         temp = (mid-x+1) - query(x,mid,0,n-1,1);
     77         if(temp < key)
     78         str = mid + 1;
     79         else
     80         end = mid;
     81     }
     82     return str;
     83 }
     84 int bin(int x,int key)
     85 {
     86     int str,end,mid,temp;
     87     str = x;end = n-1;
     88     temp = (n-x) - query(x,n-1,0,n-1,1);
     89     if(key > temp)
     90     key = temp;
     91     while(str < end)
     92     {
     93         mid = (str + end)/2;
     94         temp = (mid-x+1) - query(x,mid,0,n-1,1);
     95         if(temp < key)
     96         str = mid + 1;
     97         else
     98         end = mid;
     99     }
    100     return str;
    101 }
    102 int main()
    103 {
    104     int t,m,i,a,b,k;
    105     scanf("%d",&t);
    106     while(t--)
    107     {
    108         scanf("%d%d",&n,&m);
    109         memset(sum,0,sizeof(sum));
    110         memset(lz,0,sizeof(lz));
    111         for(i = 1;i <= m;i ++)
    112         {
    113             scanf("%d%d%d",&k,&a,&b);
    114             if(k == 1)
    115             {
    116                 a = bis(a,1);
    117                 if(a != -1)
    118                 b = bin(a,b);
    119                 if(a == -1)
    120                 printf("Can not put any one.
    ");
    121                 else
    122                 {
    123                     printf("%d %d
    ",a,b);
    124                     update(a,b,1,0,n-1,1);
    125                 }
    126             }
    127             else
    128             {
    129                 printf("%d
    ",query(a,b,0,n-1,1));
    130                 update(a,b,-1,0,n-1,1);
    131             }
    132         }
    133         printf("
    ");
    134     }
    135     return 0;
    136 }
  • 相关阅读:
    0401. Binary Watch (E)
    0436. Find Right Interval (M)
    0151. Reverse Words in a String (M)
    1344. Angle Between Hands of a Clock (M)
    0435. Non-overlapping Intervals (M)
    0434. Number of Segments in a String (E)
    0063. Unique Paths II (M)
    0062. Unique Paths (M)
    0100. Same Tree (E)
    0190. Reverse Bits (E)
  • 原文地址:https://www.cnblogs.com/naix-x/p/3219229.html
Copyright © 2011-2022 走看看