码迷,mamicode.com
首页 > 其他好文 > 详细

玲珑学院 1149 - Buildings

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

标签:color   void   ace   als   二分   pre   ret   oid   blog   

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

标签:color   void   ace   als   二分   pre   ret   oid   blog   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!