1. 程式人生 > >玲瓏學院 1149 - Buildings

玲瓏學院 1149 - Buildings

return eof logs 思路 check -i false += col

題意:給出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