玲珑学院 1149 - Buildings
题意:给出N,k,长度为N的数列,问有多少个区间满足区间最大值-区间最小值<=k
思路:RMQ+二分
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=2e5+10; 5 int a[N],b[N]; 6 int dp1[N][20],dp2[N][20]; 7 int n,k; 8 9 void init(){ 10 memset(dp2,127,sizeof(dp2)); 11 for(int i=1;i<=n;i++) 12 dp1[i][0]=dp2[i][0]=a[i]; 13 for(int j=1;(1<<j)<=n;j++){ 14 for(int i=1;i+(1<<j)-1<=n;i++) 15 { 16 dp1[i][j]=max(dp1[i][j-1],dp1[i+(1<<(j-1))][j-1]); 17 dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]); 18 } 19 } 20 } 21 22 bool check(int x,int y){ 23 int kk=0; 24 while((1<<(kk+1))<=y-x+1) kk++; 25 int Max=max(dp1[x][kk],dp1[y-(1<<kk)+1][kk]); 26 int Min=min(dp2[x][kk],dp2[y-(1<<kk)+1][kk]); 27 // cout<<Max<<" "<<Min<<" "<<x<<" "<<kk<<" "<<(y-(1<<kk)+1)<<" "<<kk<<endl; 28 if(Max-Min<=k) return true; 29 return false; 30 } 31 int main(){ 32 33 scanf("%d%d",&n,&k); 34 for(int i=1;i<=n;i++){ 35 scanf("%d",&a[i]); 36 } 37 init(); 38 ll sum=0; 39 for(int i=1;i<=n;i++){ 40 int l=i,r=n,mid,ans=i-1; 41 while(l<=r){ 42 mid=(l+r)>>1; 43 if(check(i,mid)){ 44 ans=mid; 45 l=mid+1; 46 } 47 else r=mid-1; 48 } 49 50 sum+=ans-i+1; 51 } 52 cout<<sum<<endl; 53 }