玲珑学院 1149 - Buildings

Posted 早知如此绊人心,何如当初莫相识。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玲珑学院 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 }

 

以上是关于玲珑学院 1149 - Buildings的主要内容,如果未能解决你的问题,请参考以下文章

玲珑杯 Round 19 B Buildings (RMQ + 二分)

“玲珑杯”ACM比赛 Round #19 B -- Buildings

玲珑学院 1010 - Alarm

玲珑学院 1127 咸鱼文章

玲珑学院 1050 - array

玲珑学院 1052 - See car