玲珑杯”ACM比赛 Round #19 B 维护单调栈
Posted 半根毛线code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玲珑杯”ACM比赛 Round #19 B 维护单调栈相关的知识,希望对你有一定的参考价值。
1149 - Buildings
Time Limit:2s Memory Limit:128MByte
Submissions:588Solved:151
DESCRIPTION
There are nn buildings lined up, and the height of the ii-th house is hihi.
An inteval [l,r][l,r](l≤r)(l≤r) is harmonious if and only if max(hl,…,hr)−min(hl,…,hr)≤kmax(hl,…,hr)−min(hl,…,hr)≤k.
Now you need to calculate the number of harmonious intevals.
INPUT
The first line contains two integers n(1≤n≤2×105),k(0≤k≤109)n(1≤n≤2×105),k(0≤k≤109). The second line contains nn integers hi(1≤hi≤109)hi(1≤hi≤109).
OUTPUT
Print a line of one number which means the answer.
SAMPLE INPUT
3 1
1 2 3
SAMPLE OUTPUT
5
HINT
Harmonious intervals are: [1,1],[2,2],[3,3],[1,2],[2,3][1,1],[2,2],[3,3],[1,2],[2,3].
题意:给你一个长度为n的序列 问有多少区间 使得 区间最大值-区间最小值<=k
题解:单调栈处理出以a[i]为最小值的区间左界右界 组合出合法的区间 注意 (同一左界右界)或者称为同一块 下的最小值可能会有重复
从左向右遍历时 将当前值的左界改为(同一块中上一个相同值的位置+1) 具体看代码;
1 #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <algorithm> 7 #include <cmath> 8 #include <cctype> 9 #include <map> 10 #include <set> 11 #include <queue> 12 #include <bitset> 13 #include <string> 14 #include <complex> 15 #define ll long long 16 #define mod 1000000007 17 using namespace std; 18 ll n,k; 19 ll a[200005]; 20 ll l[200005],r[200005]; 21 map<ll,map<ll,ll>> mp; 22 int main() 23 { 24 scanf("%lld %lld",&n,&k); 25 for(int i=1; i<=n; i++) 26 scanf("%lld",&a[i]); 27 a[0]=-1ll; 28 a[n+1]=-1ll; 29 l[1]=1ll; 30 for(int i=2; i<=n; i++) //关键******** 31 { 32 ll temp=i-1; 33 while(a[temp]>=a[i])//维护一个递增的序列 34 temp=l[temp]-1; 35 l[i]=temp+1; 36 } 37 r[n]=n; 38 for (int i=n-1; i>=1; i--) 39 { 40 ll temp=i+1; 41 while(a[temp]>=a[i]) 42 temp=r[temp]+1; 43 r[i]=temp-1; 44 } 45 ll ans=0; 46 for(int i=1; i<=n; i++) 47 { 48 ll x=0,y=0; 49 if(mp[l[i]][r[i]]!=0){//去重 更改l[i] 50 ll now=l[i]; 51 l[i]=mp[l[i]][r[i]]; 52 mp[now][r[i]]=i+1; 53 } 54 else 55 mp[l[i]][r[i]]=i+1; 56 for(int j=i-1; j>=l[i]; j--) 57 { 58 if((a[j]-a[i])<=k) 59 x++; 60 else 61 break; 62 } 63 for(int j=i+1; j<=r[i]; j++) 64 { 65 if((a[j]-a[i])<=k) 66 y++; 67 else 68 break; 69 } 70 ans=ans+x*y+x+y+1ll; 71 } 72 printf("%lld\n",ans); 73 return 0; 74 }
以上是关于玲珑杯”ACM比赛 Round #19 B 维护单调栈的主要内容,如果未能解决你的问题,请参考以下文章