• hdu 4616 Vases and Flowers 线段树


    sum[k]表示对应区间内部,空的花瓶的数量。

    对于插花,那么从A开始插F朵花,就是找到从A开始时第一个1和第F个1,然后把这一段全部改0。注意到可能插到结尾花还多,所以先求A到n的空瓶数量和F取个min。

    对于拿花,直接把对应区间全部赋值1就行了。

    如何找到第rk个1,需要都带一个log,可以在外面调用二分,也可以在内部调用区间求和来判断往左往右向哪走。

    lzy表示-1才表示没有lzy,这个细节出错调了一会...

      1 #include <cstdio>
      2 #include <algorithm>
      3 using namespace std;
      4 typedef long long ll;
      5 int n,m,T;
      6 ll sum[210000],lzy[210000];
      7 void build(int k,int l,int r)
      8 {
      9     lzy[k] = -1;
     10     if (l == r)
     11     {
     12         sum[k] = 1;
     13         return;
     14     }
     15     int mid = l + r >> 1;
     16     build(k << 1,l,mid);
     17     build(k << 1 | 1,mid + 1,r);
     18     sum[k] = sum[k << 1] + sum[k << 1 | 1]; 
     19 }
     20 void down(int k,int l,int r)
     21 {
     22     if (l == r)
     23     {
     24         lzy[k] = -1;
     25         return;
     26     }
     27     if (lzy[k] == -1)
     28         return;
     29     int mid = l + r >> 1;
     30     sum[k << 1] = (mid - l + 1) * lzy[k];
     31     sum[k << 1 | 1] = (r - mid) * lzy[k];
     32     lzy[k << 1] = lzy[k];
     33     lzy[k << 1 | 1] = lzy[k];
     34     lzy[k] = -1;
     35 }
     36 void chg(int k,int l,int r,int x,int y,int v)
     37 {
     38     if (x <= l && r <= y)
     39     {
     40         lzy[k] = v;
     41         sum[k] = v * (r - l + 1);
     42         return;
     43     }
     44     if (lzy[k]) down(k,l,r);
     45     int mid = l + r >> 1;
     46     if (x <= mid) chg(k << 1,l,mid,x,y,v);
     47     if (y >= mid + 1) chg(k << 1 | 1,mid + 1,r,x,y,v);
     48     sum[k] = sum[k << 1] + sum[k << 1 | 1];
     49 }
     50 int qry_sum(int k,int l,int r,int x,int y)
     51 {
     52     if (x <= l && r <= y) return sum[k];
     53     down(k,l,r);
     54     int mid = l + r >> 1,tot = 0;
     55     if (x <= mid) tot += qry_sum(k << 1,l,mid,x,y);
     56     if (y >= mid + 1) tot += qry_sum(k << 1 | 1,mid + 1,r,x,y);
     57     return tot; 
     58 }
     59 int qry_loc(int k,int l,int r,int x,int y,int rk)
     60 {
     61     if (l == r) return l;
     62     down(k,l,r);
     63     int mid = l + r >> 1;
     64     if (x >= mid + 1)
     65         return qry_loc(k << 1 | 1,mid + 1,r,x,y,rk);
     66     if (y <= mid)
     67         return qry_loc(k << 1,l,mid,x,y,rk);
     68     int t = qry_sum(k << 1,l,mid,x,y);
     69     if (t >= rk) return qry_loc(k << 1,l,mid,x,y,rk);
     70     return qry_loc(k << 1 | 1,mid + 1,r,x,y,rk - t); 
     71 }
     72 int main()
     73 {
     74     for (scanf("%d",&T);T;T--)
     75     {
     76         scanf("%d%d",&n,&m);
     77         build(1,1,n); 
     78         int opt,tx,ty,tv,tv1,tv2;
     79         for (int i = 1;i <= m;i++)
     80         {
     81             scanf("%d%d%d",&opt,&tx,&ty);
     82             
     83             if (opt == 1)
     84             {
     85                 tx++;
     86                 tv = qry_sum(1,1,n,tx,n);
     87                 if (tv == 0)
     88                 {
     89                     printf("Can not put any one.
    ");
     90                     continue;
     91                 }
     92                 tv1 = qry_loc(1,1,n,tx,n,1);
     93                 tv2 = qry_loc(1,1,n,tx,n,min(tv,ty));
     94                 printf("%d %d
    ",tv1 - 1,tv2 - 1);
     95                 chg(1,1,n,tv1,tv2,0);
     96             }else
     97             {
     98                 tx++; ty++;
     99                 printf("%d
    ",ty - tx + 1 - qry_sum(1,1,n,tx,ty));
    100                 chg(1,1,n,tx,ty,1);
    101             }
    102         }
    103         printf("
    ");
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    算法之路 level 01 problem set
    算法原理与实践(链表)
    散列表(HashTable)
    系统设计与实践(实战演练)
    桶排序 + 基数排序
    算法原理与实践(二叉树)
    Total Difference String
    【翻译】std::list::remove
    【翻译】std::remove
    Observer模式实践
  • 原文地址:https://www.cnblogs.com/iat14/p/12195800.html
Copyright © 2020-2023  润新知