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 }
来源:https://www.cnblogs.com/iat14/p/12195800.html