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\n", ans[i]); 76 } 77 return 0; 78 }