链接:https://ac.nowcoder.com/acm/contest/84527/C 来源:牛客网
做法
暴力解法就是对于x的每一个位置去遍历最小和最大长度,那么复杂度肯定爆炸,我们先考虑一下最小长度和最大长度的关系,对于一个数来说,如果拓展的最小长度的最小值都小于x,那么最大也只能更小,所以只需要去看最小长度即可,那么就排除了最大长度的影响,那么就需要去优化循环向左向右的过程,我们定义两个数组l,r,l代表的含义为,第i个位置最多向左延展
l【i】个单位能保证i这个位置的元素最小,r数组同理,那么只需要用一个栈去模拟这个过程就能在on的复杂度内完成预处理,因为如果前面一个值小于后面的值,那么每次遇到这个值都会停止循环,如果现在的值比之前一个值小,那么之前被清除的元素在这个元素身上也同样适用,所以是一个单调栈的运用,最后更新一下数组即可。特别的,这种操作可以更新到一个最大长度,但对于比这个长度小的情况会忽略掉,所以需要从后往前再更新一下,为什么从后往前,就是依据之前的推论,如果长度长的都是这个最小值,那么长度短的一定成立,如果当前这个长度有一个最小值则不受影响,如果之前操作被忽略才会被更新。
//本题代码
#include<bits/stdc++.h>
#define endl "\n"
#define ll long long
/*inline __int128 read(){
__int128 x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if(ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(__int128 x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
print(x / 10);
putchar(x % 10 + '0');
}*/
//dont forget to check long long
//别写重变量名
//记得判越界
//别死磕
//处理字符串删掉关流
//用__int128时记得删掉关流
struct node
{
int num,pos;
};
int l[100010],r[100010];
int ans[100010];
std::stack<node> q;
void slove()
{
int n;
std::cin>>n;
std::vector<int> a(n+1);
for(int i=1;i<=n;i++) std::cin>>a[i];
q.push({0,0});
for(int i=1;i<=n;i++)
{
int tmp=a[i];
while(tmp<=q.top().num) q.pop();
l[i]=i-q.top().pos-1;
q.push({tmp,i});
}
while(!q.empty()) q.pop();
q.push({0,n+1});
for(int i=n;i>=1;i--)
{
int tmp=a[i];
while(tmp<=q.top().num) q.pop();
r[i]=q.top().pos-i-1;
q.push({tmp,i});
}
for(int i=1;i<=n;i++)
{
int p=l[i]+r[i]+1;
ans[p]=std::max(ans[p],a[i]);
}
for(int i=n;i>=1;i--)
{
ans[i]=std::max(ans[i+1],ans[i]);
}
int m;
std::cin>>m;
while(m--)
{
int x,l,r;
std::cin>>x>>l>>r;
if(ans[l]<x) std::cout<<"No"<<endl;
else std::cout<<"Yes"<<endl;
}
}
int main()
{
int T=1;
//std::cin>>T;
while(T--) {
slove();
}
return 0;
}