“玲珑杯”ACM比赛 Round #19 B -- Buildings
#include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<cmath> #include<set> #include<stack> #define ll long long #define pb push_back #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)>(y)?(y):(x)) #define cls(name,x) memset(name,x,sizeof(name))//0或-1 #define fs first #define sc second #define mp make_pair #define L(x) (1<<x) using namespace std; const int inf=1e9+10; const ll llinf=1e16+10; const int maxn=2e5+10; const int maxm=2e5+10; const int mod=1e9+7; int n,k; int dp[2][maxn][20]; int h[maxn]; int query(int L,int R) { int x=log(R-L+1)/log(2); int t1=max(dp[0][L][x],dp[0][R-L(x)+1][x]); int t2=min(dp[1][L][x],dp[1][R-L(x)+1][x]); return t1-t2; } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d %d",&n,&k)) { for(int i=1;i<=n;i++) scanf("%d",&h[i]); for(int i=1;i<=n;i++) dp[0][i][0]=dp[1][i][0]=h[i]; for(int j=1;L(j)<=n;j++) for(int i=1;i+L(j)-1<=n;i++) { dp[0][i][j]=max(dp[0][i][j-1],dp[0][i+L(j-1)][j-1]); dp[1][i][j]=min(dp[1][i][j-1],dp[1][i+L(j-1)][j-1]); } ll ans=0; for(int i=1;i<=n;i++) { int l=i,r=n; int res=i; while(l<=r) { int mid=(l+r)/2; int t=query(i,mid); if(t<=k) { res=max(res,mid); l=mid+1; } else r=mid-1; } ans+=res-i+1; } printf("%lld\n",ans); } return 0; }