Alyona and Spreadsheet
思路
一开始感觉是一个二维版的单调递增的序列,但是发现这个题目的数据有点大,(n * m <= 100000),数组的范围不好固定,所以只能用滚动数组的形式来写了。
我们定义三个数组,(a[N], ans[N], column[N]), 分别记录的是上一行的元素,每一行可以到达的最小行,当前这一行中,每一列可以到达的最最小行。然后滚动(a[N])数组来更新(ans[N], column[N])数组。
为了方便理解,样例的(column[N])数组的打印如下。
样例
5 4
1 2 3 5
3 1 3 2
4 5 2 3
5 5 3 2
4 4 3 4
6
1 1
2 5
4 5
3 5
1 3
1 5
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], ans[N], column[N], n, m, k, l, r, t;
int main() {
// freopen("in.txt", "r", stdin);
scanf("%d %d", &n, &m);
for(int i = 1; i <= m; i++) {
scanf("%d", &a[i]);
column[i] = 1;
}
// for(int j = 1; j <= m; j++)
// printf("%d%c", column[j], j == m ? '
' : ' ');
ans[1] = 1;
for(int i = 2; i <= n; i++) {
ans[i] = i;
for(int j = 1; j <= m; j++) {
scanf("%d", &t);
if(t < a[j]) column[j] = i;
a[j] = t;
if(column[j] < ans[i])
ans[i] = column[j];
}
// for(int j = 1; j <= m; j++)
// printf("%d%c", column[j], j == m ? '
' : ' ');
}
scanf("%d", &k);
while(k--) {
scanf("%d %d", &l, &r);
if(ans[r] <= l) puts("Yes");
else puts("No");
}
return 0;
}