首页 > 其他 > 详细

玲珑学院 1149 - Buildings

时间:2017-07-29 18:07:31      阅读:268      评论:0      收藏:0      [点我收藏+]

题意:给出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 }

 

玲珑学院 1149 - Buildings

原文:http://www.cnblogs.com/hhxj/p/7256863.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!