hdu5289 ST表+二分

用裸的St表+暴力枚举查询时稳TLE的,可以枚举每个区间的起点+二分满足条件的区间右端,这样复杂度是O(nlogn)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 100005
#define ll long long
int T,n,k,a[maxn],mx[maxn][],mi[maxn][];
ll ans;
void ST(){
ans=;
for(int i=;i<=n;i++) mx[i][]=mi[i][]=a[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++){
mx[i][j]=max(mx[i][j-],mx[i+(<<(j-))][j-]);
mi[i][j]=min(mi[i][j-],mi[i+(<<(j-))][j-]);
}
}
int query(int L,int R){
int kk=log2(R-L+);
int tmp1=max(mx[L][kk],mx[R-(<<kk)+][kk]);
int tmp2=min(mi[L][kk],mi[R-(<<kk)+][kk]);
// cout << tmp1 << " " <<tmp2 <<'\n';
return tmp1-tmp2;
}
int main(){
cin >> T;
while(T--){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
ST(); for(int i=;i<=n;i++){
int l=i,r=n,res=;
while(l<=r){
int mid=l+r>>;
int tmp=query(i,mid);
if(tmp<k) res=mid,l=mid+;
else r=mid-;
}
ans+=l-i;
} printf("%lld\n",ans);
}
}
上一篇:采用css实现流动的边框


下一篇:如何允许你的应用移动到SD卡?(转至http://blog.csdn.net/feng88724/article/details/6946670)