题目大意:
给你一个N*M的矩阵,一共有k次查询,每次查询区间【L,R】表示询问是否在从第L行到第R行存在某一列是非递减存在的(从上到下)。
思路:
1、看问题寻本质,观察到N*M最大不超过1e5.那么我们就从这1e5着手。
我们可以直接O(M*N)每一次枚举一列,处理出来一个数组tmp【i】=x,表示这一列中,从第x行到第i行是非递减存在的。
那么我们过程维护一个最大tmp【i】作为pre【i】=x,表示第x行到第i行是满足某一列是非递减存在的。
2、那么对应查询的时候,只要pre【R】<=L即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
vector<int >a[100500];
int pre[100500];
int ans[100500];
int tmp[100500];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
{
a[i].push_back(0);
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);
a[i].push_back(x);
}
}
memset(pre,0x3f3f3f3f,sizeof(pre));
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
if(i==1)
{
tmp[i]=1;
}
else
{
if(a[i][j]>=a[i-1][j])tmp[i]=tmp[i-1];
else tmp[i]=i;
}
}
for(int i=1;i<=n;i++)
{
pre[i]=min(pre[i],tmp[i]);
}
}
int q;
scanf("%d",&q);
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
if(pre[r]<=l)printf("Yes\n");
else printf("No\n");
}
}
}