线段树

http://acm.hdu.edu.cn/showproblem.php?pid=4302

  1 #include<iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<ctime>

  6 

  7 using namespace std;

  8 

  9 typedef long long ll;

 10 const int maxn = 100100;

 11 const int inf = (-1u)>>2;

 12 int L, n;

 13 struct Node

 14 {

 15     int max_, min_;

 16     int num;

 17 }node[maxn * 4];

 18 #define lc (pos << 1)

 19 #define rc (pos << 1 | 1)

 20 

 21 void build(int pos, int l,int r)

 22 {

 23     if(l > r)    return;

 24 

 25     node[pos].num = 0;

 26     node[pos].min_ = inf;

 27     node[pos].max_ = -inf;

 28 

 29     if(r == l)    return;

 30 

 31 

 32     int mid = (l + r) >> 1;

 33     build(lc, l, mid);

 34     build(rc, mid + 1, r);

 35 }

 36 

 37 void insert(int pos, int l,int r,int p, int dx)//在l到r中插入p

 38 {

 39     if(l > r || p < l || p > r)    return;

 40     if(l == r)

 41     {

 42         node[pos].num += dx;

 43         if(node[pos].num)

 44             node[pos].max_ = node[pos].min_ = p;

 45         else

 46         {

 47             node[pos].min_ = inf;

 48             node[pos].max_ = -inf;

 49         }

 50         return;

 51     }

 52 

 53     int mid = (l + r) >> 1;

 54     insert(lc, l, mid, p, dx);

 55     insert(rc, mid + 1, r, p, dx);

 56 

 57     node[pos].max_ = max(node[lc].max_, node[rc].max_);

 58     node[pos].min_ = min(node[lc].min_, node[rc].min_);

 59 }

 60 

 61 int search_max(int pos, int l,int r,int x, int y)//在x到y这一段找最大值

 62 {

 63     if(y < l || x > r || l > r || x > y)    return -inf;

 64     if(x <= l && r <= y)    return node[pos].max_;

 65 

 66     int mid = (l + r) >> 1;

 67 

 68     return max(search_max(lc, l, mid, x, y), search_max(rc, mid + 1, r, x, y));

 69 }

 70 

 71 int search_min(int pos, int l,int r,int x, int y)

 72 {

 73     if(y < l || x > r || l > r || x > y)    return inf;

 74     if(x <= l && r <= y)    return node[pos].min_;

 75 

 76     int mid = (l + r) >> 1;

 77 

 78     return min(search_min(lc, l, mid, x, y), search_min(rc, mid + 1, r, x, y));

 79 }

 80 

 81 int main()

 82 {

 83     int T;

 84     scanf("%d", &T);

 85     for(int cas = 1; cas <= T; cas++)

 86     {

 87         scanf("%d%d", &L, &n);

 88         build(1, 0, L);

 89         ll ans = 0;

 90         scanf(" ");

 91         int now = 0, dir = 1;

 92         for(int i = 0; i < n; i++)

 93         {

 94             int flag, x;

 95             char s[100];

 96             gets(s);

 97             sscanf(s, "%d%d", &flag, &x);

 98             if(flag)

 99             {

100                 int l = search_max(1, 0, L, 0, now), r = search_min(1, 0, L, now, L);

101 

102                 if(l <= -inf && r >= inf)

103                     continue;

104                 else

105                 if(l <= -inf)

106                     ans += r - now, now = r, dir = 1;

107                 else

108                 if(r >= inf)

109                     ans += now - l, now = l, dir = 0;

110                 else

111                 if(now - l < r - now)

112                     ans += now - l, now = l, dir = 0;

113                 else

114                 if(now - l > r - now)

115                     ans += r - now, now = r, dir = 1;

116                 else

117                 if(dir)

118                     ans += r - now, now = r, dir = 1;

119                 else

120                     ans += now - l, now = l, dir = 0;

121 

122                 insert(1, 0, L, now, -1);

123             }

124             else

125                 insert(1, 0, L, x, 1);

126         }

127 

128         printf("Case %d: %lld\n", cas, ans);

129     }

130 

131     //printf("time=%d\n", clock() - begin);

132     return 0;

133 }

 

你可能感兴趣的:(线段树)