HDU 4614 Vases and Flowers 線段樹+二分
阿新 • • 發佈:2017-08-08
too others tput sometimes 標記傳遞 scan mean 二分 set
For each test case, the first line contains two integers N(1 < N < 50001) and M(1 < M < 50001). N is the number of vases, and M is the operations of Alice. Each of the next M lines contains three integers. The first integer of one line is K(1 or 2). If K is 1, then two integers A and F follow. It means Alice receive F flowers and try to put a flower in the vase A first. If K is 2, then two integers A and B follow. It means the owner would like to clean the vases numbered from A to B(A <= B).
Output one blank line after each test case.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4614
題意:N個花瓶,兩種操作。
操作1:從第a個花瓶開始放花,放最多f個,如果花瓶已經有花就跳過,直到放完,或者無更多花瓶,要求輸出這次放花的第一個位置和最後一個位置,如果沒放就輸出Cannot。。。
操作2:將花瓶a到b區間內的花都扔了,然後輸出扔掉的花的數目。
解題思路:花瓶有花為0,無花為1,那麽實際上這是一個區間更新以及求和,求左右端點的問題。線段樹節點維護一個 sum--區間和,lid--最左端為1的點,rid--最右端為1的點。對於操作1,首先找到放的區間。即如果能放這麽多花,最後一個可以放的位置在哪。當然如果不能放花則直接輸出cannot。。。 如果能放的比要放的少就是從a到n,否則二分查找以a為起點的空花瓶個數為要放的花的數目f的位置,查詢,更新就行。
理清思路的話,不算難,就是過程略復雜。
順便說下這幾天做線段樹對延遲標記的理解:延遲標記的作用不用多說,要註意的是更新到一個區間時,如果包含了整個區間的話,就加上延遲標記,同時要更新整個區間的值。如果需要往左右孩子更新的話,那麽就將延遲標記傳遞給左右孩子,同時更新他們節點的值。所以,對於延遲標記來講,一個要求就是能直接計算出它所帶來的屬性值的變化。
代碼:
1 const int maxn = 5e4 + 5;
2 struct node{
3 int sum, lazy;
4 int lid, rid;
5 };
6 node tree[maxn * 4 ];
7 int n, m;
8
9
10 void build(int l, int r, int k){
11 tree[k].sum = (r - l + 1);tree[k].lazy = 0;
12 tree[k].lid = l; tree[k].rid = r;
13 if(l == r) return;
14 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;
15 build(l, mid, lc);
16 build(mid + 1 , r, rc);
17 }
18 void pushdown(int l, int r, int k){
19 if(tree[k].lazy == 0) return;
20 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;
21 if(tree[k].lazy == 1){
22 tree[lc].lazy = 1; tree[rc].lazy = 1;
23 tree[lc].sum = (mid - l + 1); tree[lc].lid = l; tree[lc].rid = mid;
24 tree[rc].sum = (r - mid); tree[rc].lid = mid + 1; tree[rc].rid = r;
25 }
26 else if(tree[k].lazy == -1){
27 tree[lc].lazy = -1; tree[rc].lazy = -1;
28 tree[lc].sum = 0; tree[lc].lid = 0; tree[lc].rid = 0;
29 tree[rc].sum = 0; tree[rc].lid = 0; tree[rc].rid = 0;
30 }
31 tree[k].lazy = 0;
32 }
33 void pushup(int l, int r, int k){
34 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;
35 tree[k].sum = tree[lc].sum + tree[rc].sum;
36 if(tree[lc].lid != 0) tree[k].lid = tree[lc].lid;
37 else if(tree[rc].lid != 0) tree[k].lid = tree[rc].lid;
38 else tree[k].lid = 0;
39 if(tree[rc].rid != 0) tree[k].rid = tree[rc].rid;
40 else if(tree[lc].rid != 0) tree[k].rid = tree[lc].rid;
41 else tree[k].rid = 0;
42 }
43 void update(int ul, int ur, int x, int l, int r, int k){
44 if(ul <= l && ur >= r){
45 tree[k].lazy = x;
46 if(x == 1){
47 tree[k].sum = (r - l + 1);
48 tree[k].lid = l; tree[k].rid = r;
49 }
50 else if(x == -1){
51 tree[k].sum = 0;
52 tree[k].lid = tree[k].rid = 0;
53 }
54 return;
55 }
56 if(ul > r || ur < l) return;
57 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;
58 pushdown(l, r, k);
59 update(ul, ur, x, l, mid, lc);
60 update(ul, ur, x, mid + 1, r, rc);
61 pushup(l, r, k);
62 }
63 int query_left(int ql, int qr, int l, int r, int k){
64 if(ql <= l && qr >= r){
65 return tree[k].lid;
66 }
67 if(ql > r || qr < l) return 0;
68 pushdown(l, r, k);
69 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;
70 int q1 = query_left(ql, qr, l, mid, lc);
71 int q2 = query_left(ql, qr, mid + 1, r, rc);
72 if(q1 == 0) return q2;
73 return q1;
74 }
75 int query_right(int ql, int qr, int l, int r, int k){
76 if(ql <= l && qr >= r){
77 return tree[k].rid;
78 }
79 if(ql > r || qr < l) return 0;
80 pushdown(l, r, k);
81 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;
82 int q1 = query_right(ql, qr, l, mid, lc);
83 int q2 = query_right(ql, qr, mid + 1, r, rc);
84 if(q2 == 0) return q1;
85 return q2;
86 }
87 int sum(int sl, int sr, int l, int r, int k){
88 if(sl <= l && sr >= r){
89 return tree[k].sum;
90 }
91 if(sl > r || sr < l) return 0;
92 pushdown(l, r, k);
93 int mid = (l + r) >> 1, lc = k << 1, rc = k << 1 | 1;
94 return sum(sl, sr, l, mid, lc) + sum(sl, sr, mid + 1, r, rc);
95 }
96 int check(int u, int f){
97 int tmp = sum(u, n, 1, n, 1);
98 if(tmp == 0) return -1;
99 else if(tmp <= f) return n;
100 int l = u, r = n;
101 while(l < r){
102 int mid = (l + r) >> 1;
103 tmp = sum(u, mid, 1, n, 1);
104 if(tmp >= f) r = mid;
105 else l = mid + 1;
106 }
107 return l;
108 }
109
110 int main(){
111 int T;
112 scanf("%d", &T);
113 while(T--){
114 memset(tree, 0, sizeof(tree));
115 scanf("%d %d", &n, &m);
116 build(1, n, 1);
117 while(m--){
118 int k, a, b;
119 scanf("%d %d %d", &k, &a, &b);
120 if(k == 1){
121 a++;
122 int tmp = check(a, b);
123 if(tmp == -1) {
124 puts("Can not put any one.");
125 continue;
126 }
127 int u = query_left(a, tmp, 1, n, 1);
128 int v = query_right(a, tmp, 1, n, 1);
129 printf("%d %d\n", u - 1, v - 1);
130 update(a, tmp, -1, 1, n, 1);
131 }
132 else{
133 a++;b++;
134 int u = b - a + 1 - sum(a, b, 1, n, 1);
135 printf("%d\n", u);
136 update(a, b, 1, 1, n, 1);
137 }
138 }
139 puts("");
140 }
141 }
題目:
Vases and Flowers
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3574 Accepted Submission(s): 1460
Input The first line contains an integer T, indicating the number of test cases.
For each test case, the first line contains two integers N(1 < N < 50001) and M(1 < M < 50001). N is the number of vases, and M is the operations of Alice. Each of the next M lines contains three integers. The first integer of one line is K(1 or 2). If K is 1, then two integers A and F follow. It means Alice receive F flowers and try to put a flower in the vase A first. If K is 2, then two integers A and B follow. It means the owner would like to clean the vases numbered from A to B(A <= B).
Output For each operation of which K is 1, output the position of the vase in which Alice put the first flower and last one, separated by a blank. If she can not put any one, then output ‘Can not put any one.‘. For each operation of which K is 2, output the number of discarded flowers.
Output one blank line after each test case.
Sample Input 2 10 5 1 3 5 2 4 5 1 1 8 2 3 6 1 8 8 10 6 1 2 5 2 3 4 1 0 8 2 2 5 1 4 4 1 2 3
Sample Output [pre]3 7 2 1 9 4 Can not put any one. 2 6 2 0 9 4 4 5 2 3 [/pre]
Author SYSU
Source 2013 Multi-University Training Contest 2
HDU 4614 Vases and Flowers 線段樹+二分