题目链接:http://codeforces.com/contest/777/problem/C
预处理出LIS的值,每次更新LIS的时候,假设符合条件则f(i,j)=f(i-1,j)+1,这个时候额外记录一个dp(i),代表到第i行时前面最远到哪里。
更新dp(i)=min(dp(i), i-f(i,j)+1)即可。反过来记录i行后最远就不行,因为有可能更新不到。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef pair<int, int> pii; 5 const int maxn = 100100; 6 int n, m, q, l, r; 7 vector<vector<int>> a, f; 8 int dp[maxn]; 9 10 signed main() { 11 // freopen("in", "r", stdin); 12 while(~scanf("%d%d",&n,&m)) { 13 a.clear(); f.clear(); 14 memset(dp, 0x7f, sizeof(dp)); 15 a = vector<vector<int>>(n+1); 16 f = vector<vector<int>>(n+1); 17 for(int i = 0; i <= n; i++) { 18 a[i] = vector<int>(m+1); 19 f[i] = vector<int>(m+1); 20 } 21 for(int i = 1; i <= n; i++) { 22 dp[i] = i; 23 for(int j = 1; j <= m; j++) { 24 scanf("%d", &a[i][j]); 25 } 26 } 27 for(int j = 1; j <= m; j++) { 28 f[1][j] = 1; 29 for(int i = 2; i <= n; i++) { 30 if(a[i][j] >= a[i-1][j]) { 31 f[i][j] = f[i-1][j] + 1; 32 dp[i] = min(dp[i], i-f[i][j]+1); 33 } 34 else f[i][j] = 1; 35 } 36 } 37 scanf("%d", &q); 38 while(q--) { 39 scanf("%d%d",&l,&r); 40 if(dp[r] <= l) puts("Yes"); 41 else puts("No"); 42 } 43 } 44 return 0; 45 }