【SPOJ】4487 Can you answer these queries VI

仍然是询问区间最大连续和,只不过多了插入和删除操作。

线段树搞不定了。。伸展树来了。

插入删除偷懒那样写了,加了读入优化卡过的。

  1 #include<cstdio>

  2 #include<iostream>

  3 #define MAX(a,b) ((a)>(b)?(a):(b))

  4 #define oo 1000000000

  5 #define MAXN 200010

  6 using namespace std;

  7 int n, a[MAXN];

  8 struct SplayTree {

  9     int root, size;

 10     int next[MAXN][2], pre[MAXN];

 11     int num[MAXN], key[MAXN];

 12     int left[MAXN], right[MAXN], sum[MAXN], val[MAXN];

 13     void NewNode(int &x, int father, int nb) {

 14         x = ++size;

 15         next[x][0] = next[x][1] = 0;

 16         pre[x] = father;

 17         num[x] = 1;

 18         key[x] = left[x] = right[x] = sum[x] = val[x] = nb;

 19     }

 20     inline void PushUp(int x) {

 21         int L, R;

 22         L = next[x][0], R = next[x][1];

 23         num[x] = num[L] + num[R] + 1;

 24         sum[x] = sum[L] + sum[R] + key[x];

 25         left[x] = MAX(left[L],sum[L]+key[x]+MAX(left[R],0));

 26         right[x] = MAX(right[R],sum[R]+key[x]+MAX(right[L],0));

 27         val[x] = MAX(val[L],val[R]);

 28         val[x] = MAX(val[x],key[x]+MAX(right[L],0)+MAX(left[R],0));

 29     }

 30     void Build(int L, int R, int &x, int father) {

 31         if (L <= R) {

 32             int mid = (L + R) >> 1;

 33             NewNode(x, father, a[mid]);

 34             Build(L, mid - 1, next[x][0], x);

 35             Build(mid + 1, R, next[x][1], x);

 36             PushUp(x);

 37         }

 38     }

 39     void Init() {

 40         size = root = 0;

 41         next[0][0] = next[0][1] = 0;

 42         pre[0] = 0;

 43         sum[0] = num[0] = 0;

 44         key[0] = left[0] = right[0] = val[0] = -oo;

 45         NewNode(root, 0, -oo);

 46         NewNode(next[root][1], root, -oo);

 47         Build(1, n, next[next[root][1]][0], next[root][1]);

 48         PushUp(next[root][1]);

 49         PushUp(root);

 50     }

 51     void Rotate(int x, int kind) {

 52         int y, z;

 53         y = pre[x];

 54         z = pre[y];

 55         next[y][!kind] = next[x][kind];

 56         pre[next[x][kind]] = y;

 57         next[z][next[z][1] == y] = x;

 58         pre[x] = z;

 59         next[x][kind] = y;

 60         pre[y] = x;

 61         PushUp(y);

 62     }

 63     void Splay(int x, int goal) {

 64         if (x != goal) {

 65             while (pre[x] != goal) {

 66                 if (next[pre[x]][0] == x)

 67                     Rotate(x, 1);

 68                 else

 69                     Rotate(x, 0);

 70             }

 71             PushUp(x);

 72             if (!goal)

 73                 root = x;

 74         }

 75     }

 76     int Select(int k) {

 77         int x;

 78         for (x = root; num[next[x][0]] + 1 != k;) {

 79             if (k <= num[next[x][0]])

 80                 x = next[x][0];

 81             else {

 82                 k -= num[next[x][0]] + 1;

 83                 x = next[x][1];

 84             }

 85         }

 86         return x;

 87     }

 88     void Insert(int k, int val) {

 89         int a, b;

 90         a = Select(k);

 91         b = Select(k + 1);

 92         Splay(a, 0);

 93         Splay(b, a);

 94         NewNode(next[b][0], b, val);

 95         PushUp(b);

 96         PushUp(a);

 97     }

 98     void Delete(int k) {

 99         int a, b;

100         a = Select(k);

101         b = Select(k + 2);

102         Splay(a, 0);

103         Splay(b, a);

104         next[b][0] = 0;

105         PushUp(b);

106         PushUp(a);

107     }

108     void Update(int k, int val) {

109         int a;

110         a = Select(k + 1);

111         key[a] = val;

112         Splay(a, 0);

113     }

114     int Query(int x, int y) {

115         x = Select(x);

116         y = Select(y + 2);

117         Splay(x, 0);

118         Splay(y, x);

119         return val[next[y][0]];

120     }

121 } spt;

122 int INT() {

123     int res;

124     char ch;

125     bool neg;

126     while (ch = getchar(), !isdigit(ch) && ch != '-')

127         ;

128     if (ch == '-') {

129         res = 0;

130         neg = true;

131     } else {

132         res = ch - '0';

133         neg = false;

134     }

135     while (ch = getchar(), isdigit(ch))

136         res = res * 10 + ch - '0';

137     return neg ? -res : res;

138 }

139 char CHAR() {

140     char res;

141     while (res = getchar(), !isalpha(res))

142         ;

143     return res;

144 }

145 int main() {

146     char ch;

147     int i, q, x, y;

148     while (~scanf("%d", &n)) {

149         for (i = 1; i <= n; i++)

150             a[i] = INT();

151         spt.Init();

152         q = INT();

153         while (q--) {

154             ch = CHAR(), x = INT();

155             if (ch != 'D')

156                 y = INT();

157             if (ch == 'I')

158                 spt.Insert(x, y);

159             else if (ch == 'D')

160                 spt.Delete(x);

161             else if (ch == 'R')

162                 spt.Update(x, y);

163             else

164                 printf("%d\n", spt.Query(x, y));

165         }

166     }

167     return 0;

168 }

你可能感兴趣的:(poj)