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 }
心之所动 且就随缘去吧