hdu 5289 RMQ运用

来源:互联网 发布:网络词孤儿是什么意思 编辑:程序博客网 时间:2024/05/17 04:59

点击打开链接

#include <iostream>#include <algorithm>#include <cmath> #include <cstdio>using namespace std;const int M = 110000;int n,m,a[M],Min[M][30],Max[M][30]; // Min[i][j] 以i开头 ~ i+2^j -1 结尾中的最小值 void RMQ(){for(int i=1;i<=n;i++){Min[i][0]=a[i];Max[i][0]=a[i];  // i开头长度为2^0 为本身 }//最大值时 dp[i][j]= max(dp[i][j-1],dp[i+2^(j-1)][j-1])for(int j=1;(1<<j)<=n;j++) //2^j不大于n {for(int i=1;i+(1<<j)-1<=n;i++){Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]);Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]);}}}int Query(int l,int r){int k;//k=log((double)(r-l+1))/log(2.0); // 使 2^k<= r-l+1 <= 2^(k+1)k=log2(r-l+1);int x=min(Min[l][k],Min[r-(1<<k)+1][k]);int y=max(Max[l][k],Max[r-(1<<k)+1][k]);if(y-x<m) return 1;else return 0;}int main(){int t;cin>>t;while(t--){cin>>n>>m;for(int i=1;i<=n;i++){scanf("%d",&a[i]);}RMQ();long long ans=0;for(int i=1;i<=n;i++) //枚举左端点   (i,p)成立 则(i,q) (q<p)肯定成立 所以找到满足的最远右端点p  则以i开头的合法个数有 p-i+1 {// (i,p)  不成立 则(i,q) (q>p)肯定不成立 最值之差只会越来越大 int pos;int l=i,r=n;while(l<=r) // 二分找到右端点 {int mid=(l+r)/2;if(Query(i,mid)) // {l=mid+1;pos=mid;}else{r=mid-1;}}ans+=(pos-i+1);}cout<<ans<<endl;}return 0;}


0 0
原创粉丝点击