Codeforces Round 1048 (Div. 2)
ABC 略
D
思考什么情况下会出现两种交换不相等的情况,出现一个数它前面有比它大的数,后面有比它小的数,即存在数后面有两个连续递减的数,我们用单调栈处理每个数最近的连续递减的数的位置,然后在给定区间内找到每个位置对应的最小的单调减位置是否在区间内
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
const int N=5e5+10;
int T,n,q,a[N];
struct RMQ
{int nn, K;vector<vector<int>> mn;void build(const vector<int>& a){nn=a.size()-1;K = __lg(max((int)1,nn))+1;mn.assign(K, vector<int>(nn+1));for(int i=1;i<=nn;i++) mn[0][i] = a[i];for(int k=1;k<K;k++){for(int i=1;i+(1<<k)-1<=nn;i++){mn[k][i]=min(mn[k-1][i],mn[k-1][i+(1<<(k-1))]);}}}int rangeMin(int l, int r){if(l>r) return INT_MAX;int k=__lg(r-l+1);return min(mn[k][l],mn[k][r-(1<<k)+1]);}
};
void solve()
{cin>>n>>q;for(int i=1;i<=n;i++)cin>>a[i];vector<int> L(n+1,0),R(n+1,n+1),stk;for(int i=1;i<=n;i++){while(!stk.empty()&&a[stk.back()]<a[i])stk.pop_back();if(stk.empty()) L[i]=0;else L[i]=stk.back();stk.push_back(i);}stk.clear();for(int i=n;i>=1;i--){while(!stk.empty()&&a[stk.back()]>a[i])stk.pop_back();if(stk.empty()) R[i]=n+1;else R[i]=stk.back();stk.push_back(i);}vector<int> lim(n+1,n+1);for(int i=1;i<=n;i++){int a=L[i],b=R[i];if(a>0&&b<=n) lim[a]=min(lim[a],b);}RMQ rmq;rmq.build(lim);while(q--){int l,r;cin>>l>>r;int m=rmq.rangeMin(l,r);if(m<=r) cout<<"NO"<<endl;else cout<<"YES"<<endl;}
}
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>T;while(T--) solve();
}