玲珑学院 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 }

 

posted on 2017-07-29 17:28  hhhhx  阅读(103)  评论(0编辑  收藏  举报

导航