http://poj.org/problem?id=3264
#include<iostream> #include<cstdio> #include<string> #include<cmath> #include<cstring> #define M 1000000 + 50 using namespace std; int a[M]; int maxs[M][100]; int mins[M][100]; int QueryMax(int L, int R) { int k = log(R - L + 1.0) / log(2.0); return max(maxs[L][k], maxs[R - (1 << k) + 1][k]); } int QueryMin(int L, int R) { int k = log(R - L + 1.0) / log(2.0); return min(mins[L][k], mins[R - (1 << k) + 1][k]); } int main() { //freopen("in.txt","r",stdin); int n, q; scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int dep = log(n * 1.0) / log(2.0); for (int i = 1; i <= n; i++) { mins[i][0] = a[i]; maxs[i][0] = a[i]; } for (int j = 1; j <= dep; j++) { for (int i = 1; i + (1 << j) - 1 <= n; i++) { maxs[i][j] = max(maxs[i][j - 1], maxs[i + (1 << (j - 1))][j - 1]); mins[i][j] = min(mins[i][j - 1], mins[i + (1 << (j - 1))][j - 1]); } } int l, r; for (int i = 1; i <= q; i++) { scanf("%d%d", &l, &r); int maxn = QueryMax(l, r); int minn = QueryMin(l, r); printf("%d\n", maxn - minn); } return 0; }
http://poj.org/problem?id=3368
查询断点处的数据值在区间[i,j]出现了k2 - k1 - 1 次;
求max(左边区间出现相同数字最多的次数,右边区间出现相同数字最多次数,k2 - k1 - 1);
有两个地方均需要此处理;
#include <iostream> #include <algorithm> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <string> #include <math.h> #include <time.h> #include <vector> #include <map> #include <set> #define M 100000 + 50 using namespace std; int a[M]; int maxn[M][30]; int QueryMax(int L, int R) { int k = log(R - L + 1.0) / log(2.0); int maxs = max(maxn[L][k], maxn[R - (1 << k) + 1][k]); int k1 = R - (1 << k) + 1, temp = a[k1], k2 = k1; while (a[k1] == temp && k1 >= L) k1--; while (a[k2] == temp && k2 <= R) k2++; maxs = max(maxs, k2 - k1 - 1); return maxs; } int main() { //freopen("in.txt","r",stdin); int n, q; while (scanf("%d", &n) && n) { memset(a, 0, sizeof(a)); scanf("%d", &q); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) maxn[i][0] = 1; int dep = log(n * 1.0) / log(2.0); for (int j = 1; j <= dep; j++) { for (int i = 1; i + (1 << j) - 1 <= n; i++) { maxn[i][j] = max(maxn[i][j - 1], maxn[i + (1 << (j - 1))][j - 1]); int k1 = i + (1 << (j - 1)), temp = a[k1], k2 = k1; while (a[k1] == temp && k1 >= i) k1--; while (a[k2] == temp && k2 < i + (1 << j)) k2++; maxn[i][j] = max(maxn[i][j], k2 - k1 - 1); } } int l, r; for (int i = 0; i < q; i++) { scanf("%d%d", &l, &r); printf("%d\n", QueryMax(l, r)); } } return 0; }
时间: 2024-11-05 13:39:09