https://codeforces.com/problemset/problem/279/C
第一次遇到这一类区间内递增递减的问题,考虑的顺序对了但是考虑的方向错了。我不应该考虑区间中间的顶峰开始往左右走,而是应该从左右往中间走。
要按结点数为 $n$ 高为 $h$ 的树,由高为 $h-1$ 的左子树或者高为 $h-1$ 的右子树转移过来。注意不要重复。
#include<bits/stdc++.h> using namespace std; #define ll long long int dpl[100005]; int dpr[100005]; int a[100005]; int n,m; int l,r; void init(){ int cur=a[1]; int curcnt=0; for(int i=1;i<=n;i++){ if(a[i]<=cur){ dpl[i]=curcnt++; //该点往左走最长的不降距离 } else curcnt=1; cur=a[i]; } cur=a[n]; curcnt=0; for(int i=n;i>=1;i--){ if(a[i]<=cur){ dpr[i]=curcnt++; //该点往右走最长的不降距离 } else curcnt=1; cur=a[i]; } /*for(int i=1;i<=n;i++){ printf("%d ",dpl[i]); } printf(" "); for(int i=1;i<=n;i++){ printf("%d ",dpr[i]); } printf(" ");*/ } void query(int l,int r){ if(dpr[l]+dpl[r]+1>=r-l+1){ puts("Yes"); } else puts("No"); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } init(); while(m--){ scanf("%d%d",&l,&r); query(l,r); } }
2019-01-16
由于某些原因导致实际的时间被更新的,文章的摘要却有些小漏洞,上下篇文章也有点毛病,强迫症很难受。