-
B - Assignment
- HDU - 5289
- 题意:给出一个数列,问其中存在多少连续子序列,子序列的最大值-最小值<m。
- 思路:枚举终点,尺取起点O(1)rmq倍增查询
-
#include<iostream> #include<cstring> #include<cmath> #include<stdio.h> using namespace std; #define maxn 200000 #define maxm 30 #define ll long long int dpmin[maxn][maxm]; int dpmax[maxn][maxm]; int a[maxn],n,q,m,k,t; void rmqinit() { for(int j=1; (1<<j)<=n; j++) for(int i=1; i+(1<<j)<n+2; i++) { dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]); dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]); } } int rmqmin(int l,int r) { int k=log(r-l+1)/log(2); return min(dpmin[l][k],dpmin[r-(1<<k)+1][k]); } int rmqmax(int l,int r) { int k=log(r-l+1)/log(2); return max(dpmax[l][k],dpmax[r-(1<<k)+1][k]); } int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%d",&a[i]); dpmin[i][0]=dpmax[i][0]=a[i]; } rmqinit(); ll ans=0; k=1; for(int i=1; i<=n; i++) { while(rmqmax(k,i)-rmqmin(k,i)>=m&&k<i)k++; ans+=(i-k+1); } printf("%lld\n",ans); } return 0; }
B - Assignment HDU - 5289-RMQ
最新推荐文章于 2018-10-28 15:11:50 发布