Topic link: https://vjudge.net/problem/CodeForces-777C
Title:
Give you a matrix of n*m, k queries, each with l,r, let you ask if there is a column in the l-r row that can satisfy the non-decreasing sequence from top to bottom.
Train of thought:
Preprocess the maximum number of rows that each point can reach. For example, if the maximum number of rows a[1][1] reaches the fourth row, then the maximum number of rows a[2][1],a[3][1] reaches the fourth row. Then the maximum value of each row is obtained, that is, the maximum row that the row can reach.
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) // Check one of the points { 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++) // Traversal of columns { 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; // Jump directly to the tmpi line } 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++) // Find the maximum of each line { 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; }