标签:acm
2 4 2 3 1 2 4 10 5 0 3 4 5 2 1 6 7 8 9
5 28HintFirst Sample, the satisfied groups include:[1,1]、[2,2]、[3,3]、[4,4] 、[2,3]
解题思路:
枚举左端点,二分查找右端点,用RMQ维护区间最大值和最小值
#include <iostream> #include <cstring> #include <cmath> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <stack> #define LL long long using namespace std; const int MAXN = 100000 + 10; int A[MAXN]; int dp1[MAXN][20], dp[MAXN][20]; int N, M; void RMQ_init_Min() { for(int i=0;i<N;i++) dp1[i][0] = A[i]; for(int j=1;(1<<j) <= N;j++) { for(int i=0;i+(1<<j) - 1 < N;i++) { dp1[i][j] = min(dp1[i][j-1], dp1[i + (1<<(j-1))][j-1]); } } } int RMQ_Min(int L, int R) { int k = 0; while(1<<(k+1) <= R - L + 1) k++; return min(dp1[L][k], dp1[R-(1<<k)+1][k]); } void RMQ_init_Max() { for(int i=0;i<N;i++) dp[i][0] = A[i]; for(int j=1;(1<<j) <= N;j++) { for(int i=0;i+(1<<j) - 1 < N;i++) { dp[i][j] = max(dp[i][j-1], dp[i + (1<<(j-1))][j-1]); } } } int RMQ_Max(int L, int R) { int k = 0; while(1<<(k+1) <= R - L + 1) k++; return max(dp[L][k], dp[R-(1<<k)+1][k]); } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &N, &M); for(int i=0;i<N;i++) scanf("%d", &A[i]); RMQ_init_Min(); RMQ_init_Max(); long long ans = 0; for(int i=0;i<N;i++) { int l = i, r = N-1; while(l <= r) { int mid = (l + r) >> 1; int low = RMQ_Min(i, mid); int high = RMQ_Max(i ,mid); //cout << l << ' ' << r << ' ' << high << ' ' <<low << endl; if(high - low < M) l = mid + 1; else r = mid - 1; } //cout << l << endl; ans += (l - i); } printf("%I64d\n", ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 5289 Assignment(2015 多校第一场二分 + RMQ)
标签:acm
原文地址:http://blog.csdn.net/moguxiaozhe/article/details/46999155