题目链接:https://vjudge.net/problem/CodeForces-777C
题意:
给你一个n*m的矩阵,k个询问,每个询问有l,r,让你求在l-r行里面有没有一列可以满足从上到下为非递减数列。
思路:
预处理每一个点能到达的行的最大值,例如,如果第a[1][1] 最大能到达第四行,那么a[2][1],a[3][1],最大能到达的都是第四行。然后求出每一行中的最大值,即为该行能到达的最大行的值
code:
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 100010;
int n, m;
int ans[N];
vector<int> ve[100000+1];
inline int checkOnePoint(int row, int col) // 检查其中一个点
{
int res = row;
row += 1;
while(row < n)
{
if(ve[row][col] < ve[row-1][col])
break;
res = row;
row ++;
}
return res;
}
inline int check()
{
for(int j=0; j < m; j++) // 一列一列的遍历
{
for(int i =0; i < n; )
{
// ans[i] = max(ans[i], checkOneCol(row, j));
if(i < n-1 && ve[i+1][j] >= ve[i][j])
{
int tmpi = i;
tmpi = checkOnePoint(i, j);
for(int k = i; k < tmpi; k++)
ve[k][j] = tmpi;
i = tmpi; // 直接跳到第tmpi行
}
else
{
ve[i][j] = i;
i++;
}
}
}
}
inline void preProcess()
{
for(int i=0; i < N; i++)
ans[i] = i;
check();
for(int i=0; i < n; i++)
{
int len = ve[i].size();
for(int j = 0; j < len; j++) // 求出每一行的最大值
{
ans[i] = max(ans[i], ve[i][j]);
}
}
}
int main()
{
// ios::sync_with_stdio(false);
// cin.tie();
scanf("%d%d", &n, &m);
int num;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
scanf("%d", &num);
ve[i].push_back(num);
}
preProcess();
int k;
scanf("%d", &k);
int l,r;
while(k--)
{
scanf("%d%d", &l, &r);
if(ans[l-1] >= r-1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}