题意很简单,区间最值之差。 rmq或线段树都可。 比较郁闷的是,G++提交3000+MS,C++1700+MS,差别很大 rmq的代码,跑了1766MS: #include <cstdio> #include <cstring> #include <iostream> #include <string> #include <cmath> using namespace std; const int MAXN = 50010; int n, q; int a[MAXN], d[16]; int stMax[MAXN][16]; int stMin[MAXN][16]; struct Node { int a, b; } query[200010]; int main() { scanf("%d%d", &n, &q); int i; for (i = 0; i < n; ++i) scanf("%d", a + i); int j; for (d[0] = 1, i = 1; i < 16; ++i) d[i] = d[i - 1] << 1; for (i = 0; i < n; ++i) stMax[i][0] = stMin[i][0] = a[i]; int k = int (log(n * 1.0) / log(2.0)) + 1; for (j = 1; j < k; ++j) for (i = 0; i < n; ++i) { if (i + d[j - 1] - 1 < n) { stMax[i][j] = max(stMax[i][j - 1], stMax[i + d[j - 1]][j - 1]); stMin[i][j] = min(stMin[i][j - 1], stMin[i + d[j - 1]][j - 1]); } else break; } for (i = 0; i < q; ++i) { scanf("%d%d", &query[i].a, &query[i].b); if (query[i].a > query[i].b) swap(query[i].a, query[i].b); } for (i = 0; i < q; ++i) { --query[i].a, --query[i].b; int k = int(log((query[i].b - query[i].a + 1)*1.0) / log(2.0)); printf("%d/n", max(stMax[query[i].a][k], stMax[query[i].b - d[k] + 1][k]) - min(stMin[query[i].a][k], stMin[query[i].b - d[k] + 1][k])); } } 线段树 跑了1672MS 稍胜一筹~~: #include <cstdio> #include <cstring> #include <iostream> #include <string> #include <cmath> using namespace std; #define inf 0x7fffffff #define MAXN 50000 #define L (i<<1) #define R ((i<<1)|1) struct Node { int Min; int Max; int s, e; } tree[MAXN << 2]; int val[MAXN + 10]; int maxVal; int minVal; inline void update(int i) { tree[i].Min = min(tree[L].Min, tree[R].Min); tree[i].Max = max(tree[L].Max, tree[R].Max); } void build(int i, int s, int e) { tree[i].s = s; tree[i].e = e; if (s < e) { int mid = (s + e) >> 1; build(L, s, mid); build(R, mid + 1, e); update(i); } else { tree[i].Min = val[tree[i].s]; tree[i].Max = val[tree[i].s]; } } void query(int i, int s, int e) { if (tree[i].s == s && tree[i].e == e) { minVal = min(minVal, tree[i].Min); maxVal = max(maxVal, tree[i].Max); return; } int mid = (tree[i].s + tree[i].e) >> 1; if (e <= mid) query(L, s, e); else if (s > mid) query(R, s, e); else { query(L, s, mid); query(R, mid + 1, e); } } int main() { int n, q; scanf("%d%d", &n, &q); int i; for (i = 1; i <= n; ++i) scanf("%d", val + i); build(1, 1, n); while (q--) { int a, b; scanf("%d%d", &a, &b); maxVal = -1; minVal = inf; query(1, a, b); printf("%d/n", maxVal - minVal); } return 0; }