hdu2795 Billboard
21年的第一题线段树
上来没看出来为啥是个线段树
看一篇题解文字第一行:
用线段树节点存储该区间内空位最大的那一行的空位长度
等等我感觉我又行了
因为没加algorithm疯狂CE
然后因为一个小失误wa一发
很快找出来了
总体感觉还行
1 #include<iostream>
2 #include<algorithm>
3 #include<cstring>
4 #include<string>
5 #include<cstdio>
6 #include<cmath>
7 using namespace std;
8 const int N = 2e5 + 10;
9
10 struct node
11 {
12 int tag;
13 }t[N << 2];
14
15 int h, w, n;
16 int a[N];
17
18 inline void push_up(int root)
19 {
20 t[root].tag = max(t[root << 1].tag, t[root << 1 | 1].tag);
21 }
22
23 inline void build(int l, int r, int root)
24 {
25 if(l == r){
26 t[root].tag = w;
27 return ;
28 }
29 int mid = (l + r) >> 1;
30 build(l, mid, root << 1);
31 build(mid + 1, r, root << 1 | 1);
32 push_up(root);
33 }
34
35 inline void upd(int l, int r, int root, int id, int val)
36 {
37 if(l == r && l == id){
38 t[root].tag -= val;
39 return ;
40 }
41 int mid = (l + r) >> 1;
42 if(id <= mid) upd(l, mid, root << 1, id, val);
43 else upd(mid + 1, r, root << 1 | 1, id, val);
44 push_up(root);
45 }
46
47 int tmp;
48 inline void query(int l, int r, int root, int val)
49 {
50 if(l == r){
51 if(t[root].tag >= val) tmp = l;
52 else tmp = -1;//这部分一开始就想到了,可能出现高度为1的面板,但手贱删掉了...
53 return ;
54 }
55 if(t[root << 1].tag < val && t[root << 1 | 1].tag < val){
56 tmp = -1;
57 return ;
58 }
59 int mid = (l + r) >> 1;
60 if(t[root << 1].tag >= val) query(l, mid, root << 1, val);
61 else query(mid + 1, r, root << 1 | 1, val);
62 }
63
64 int main(){
65 while(~scanf("%d%d%d",&h,&w,&n)){
66 int len = min(h, n);
67 build(1, len, 1);
68 for(int i = 1 ; i <= n ; i++){
69 scanf("%d",&a[i]);
70 query(1, len, 1, a[i]);
71 printf("%d\n", tmp);
72 if(tmp != -1){
73 upd(1, len, 1, tmp, a[i]);
74 }
75 }
76 }
77
78 return 0;
79 }