hfut 1287

http://acm.hfut.edu.cn/OnlineJudge/

中文题。

区间线段树,需要剪枝。n的大小有问题。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 #define ls rt<<1
 8 #define rs rt<<1|1
 9 #define lson l, m, rt<<1
10 #define rson m + 1, r, rt<<1|1
11 const int inf = 0x3f3f3f3f;
12 const int maxn = 2e4 + 5;
13 
14 struct SegTree{
15     int maxv, minv;
16     int lx, rx, sumx;//该区间左边是否被淹,右边,总的小岛数
17 }seg[maxn << 2];
18 struct Node{
19     int h, id;
20 }q[maxn];
21 int a[maxn];
22 
23 void build(int l, int r, int rt){
24     seg[rt].lx = seg[rt].rx = seg[rt].sumx = 1;
25     if (l == r){
26         seg[rt].maxv = seg[rt].minv = a[l];
27         return ;
28     }
29     int m = (l + r) >> 1;
30     build(lson);
31     build(rson);
32     seg[rt].maxv = max(seg[ls].maxv, seg[rs].maxv);
33     seg[rt].minv = min(seg[ls].minv, seg[rs].minv);
34 }
35 void pushUp(int rt){
36     seg[rt].sumx = seg[ls].sumx + seg[rs].sumx - (seg[ls].rx & seg[rs].lx);
37     seg[rt].lx = seg[ls].lx;
38     seg[rt].rx = seg[rs].rx;
39     seg[rt].minv = min(seg[ls].minv, seg[rs].minv);//
40 }
41 void update(int h, int l, int r, int rt){
42     if (h < seg[rt].minv) return;
43     if (h >= seg[rt].maxv){
44         seg[rt].minv = inf;//这句表明接下来的h对这个区间都不会再有影响,相当于减掉了这个区间否则tle
45         seg[rt].rx = seg[rt].lx = seg[rt].sumx = 0;
46         return ;
47     }
48     int m = (l + r) >> 1;
49     update(h, lson);
50     update(h, rson);
51     pushUp(rt);
52 }
53 bool cmp(Node a, Node b){
54     return a.h < b.h;
55 }
56 int ans[maxn];
57 int main(){
58     int n, m;
59     scanf("%d", &n);
60     for (int i = 1; i <= n; ++i){
61         scanf("%d", &a[i]);
62     }
63     build(1, n, 1);
64     scanf("%d", &m);
65     for (int i = 0; i < m; ++i){
66         scanf("%d", &q[i].h);
67         q[i].id = i;
68     }
69     sort(q, q + m, cmp);
70     for (int i = 0; i < m; ++i){
71         update(q[i].h, 1, n, 1);
72         ans[q[i].id] = seg[1].sumx;
73     }
74     for (int i = 0; i < m; ++i){
75         printf("%d
", ans[i]);
76     }
77     return 0;
78 }
原文地址:https://www.cnblogs.com/Missa/p/3361672.html