Codeforces 777C Alyona and Spreadsheet

Codeforces 777C Alyona and Spreadsheet

题目链接

http://codeforces.com/problemset/problem/777/C

题目大意

给你一个矩阵,多次询问,每次询问 $L$ 和 $R$ ,你需要回答是否存在一列使得L行到R行为不下降序列

题目分析

这题注意到,只要知道 $L$ 行开始,最长不下降序列最长的那列到哪个位置结束就行了,所以可以先预处理找到所有的不下降序列,就可以找到所有的以某行为起始的最长的不下降序列长度,又因为从前面几行延伸过来的其实也是不下降的,所以再求某一行结束位置和前面几行相比的最大值,查询时比较最大结束位置和 $R$ 谁大就可以了。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>

using namespace std;

int n, m;

int a[100005];

struct ex {
    int x;
    int y;
};

ex f[100005];
int cnt = 0;

int v[100005];

int t, k;

int l, r;

int geta(int x, int y){
    return a[(x - 1) * m + y];
}

int init(){
    int i, j;
    
    for(i=1;i<=m;i++){
        l = 1;
        for(j=2;j<=n;j++){
            if(geta(j, i) < geta(j - 1, i)){
                cnt++;
                f[cnt].x = l;
                f[cnt].y = j - 1;
                l = j;
            }
        }
        cnt++;
        f[cnt].x = l;
        f[cnt].y = n;
    }
    
    for(i=1;i<=cnt;i++){
        v[f[i].x] = max(v[f[i].x], f[i].y);
    }
    
    for(i=1;i<=n;i++){
        v[i] = max(v[i], v[i - 1]);
    }
    
    return 0;
}

bool query(int x, int y){
    if(v[x] >= y){
        return true;
    }else{
        return false;
    }
}

int main(){
    int i, j;
    
    scanf("%d", &n);
    scanf("%d", &m);
    
    t = n * m;
    
    for(i=1;i<=t;i++){
        scanf("%d", &a[i]);
    }
    
    init();
    
    scanf("%d", &k);
    
    for(i=1;i<=k;i++){
        scanf("%d", &l);
        scanf("%d", &r);
        if(l == r){
            printf("Yes\n");
        }else if(query(l, r)){
            printf("Yes\n");
        }else{
            printf("No\n");
        }
    }
    
    return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据