题目链接:http://codeforces.com/problemset/problem/279/C
题意:
给出 $n$ 个整数 $a[1 sim n]$,$m$ 个查询,对于一个查询 $[l_i,r_i]$,对应于子段 $a[l_i], a[l_i+1], cdots, a[r_i]$,需要你判断这个子段是不是单峰的。
此处的单峰,指的是,开始时是一段单调不减的,然后以一段单调不增结束;同时这两段的长度为零也是可以的。
题解:
令 $f[i]$ 表示第 $i$ 个整数往前走,保持单调不减的状态,最远能走多远。
相应的 $g[i]$ 表示第 $i$ 个整数往后走,保持单调不减的状态,最远能走多远。
对于所有的查询,如果 $g[l_i] + f[r_i] ge r-l+1$,就代表是单峰的。
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int n,m,a[maxn]; int f[maxn],g[maxn]; int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin>>n>>m; memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) { if(a[i-1]>=a[i]) f[i]=f[i-1]+1; else f[i]=1; } for(int i=n;i>=1;i--) { if(a[i]<=a[i+1]) g[i]=g[i+1]+1; else g[i]=1; } while(m--) { int l,r; cin>>l>>r; cout<<((g[l]+f[r]>=r-l+1)?"Yes":"No")<<' '; } }