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.\n");
 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\n",tv1 - 1,tv2 - 1);
 95                 chg(1,1,n,tv1,tv2,0);
 96             }else
 97             {
 98                 tx++; ty++;
 99                 printf("%d\n",ty - tx + 1 - qry_sum(1,1,n,tx,ty));
100                 chg(1,1,n,tx,ty,1);
101             }
102         }
103         printf("\n");
104     }
105     return 0;
106 }
posted @ 2020-01-15 11:30  IAT14  阅读(171)  评论(0编辑  收藏  举报