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 }

 

你可能感兴趣的:(T)