其他分享
首页 > 其他分享> > [CodeForces 777C] Alyona and Spreadsheet (思维 + 优化)

[CodeForces 777C] Alyona and Spreadsheet (思维 + 优化)

作者:互联网

题意

给你一个nm的矩阵(nm <= 1e5),然后给你q次询问,每次询问会给你两个数字 L 和 R ,问你在第L行到第R行中(无视其他未被选中的行的数据),是否存在一列是单调不减的。

思路

显然暴力会TLE

要问的是行区间L到R是否存在一列单调不减,意味着有L行有一列,它能单调不减的延伸到至少R行,那么我们如果能够获得这样一个数列c[i],c[i]表示第i行能够延伸的最长的长度,那么对于每次询问,我们都能O(1)判断了。

如何获取c[i]数组,做法是枚举每一列,对于每一列,行数从下往上跑,获得每一行的最大延伸长度,对于同一行的,取最大值即可获得c[i],最后通过L+c[i]是否>=R即可判断。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int c[maxn];//行最大延伸
int main()
{
    int n, m;
    cin >> n >> m;
    int a[n + 5][m + 5];
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> a[i][j];

    for(int i = 1; i <= m;i++)
    {
        a[0][i] = 0;
        a[n + 1][i] = 0;
    }


    int cnt;
    for(int j = 1; j <= m; j++)//枚举列
    {
        cnt = 0;
        for(int i = n; i >= 1; i--)//从下往上枚举行
        {
            if(a[i][j] < a[i - 1][j])
            {
                cnt = 0;
                a[i][j] = 0;
            }
            else
            {
                a[i][j] = ++cnt;//cnt为延伸长度
            }
            c[i] = max(c[i], a[i + 1][j]);//a[i+1][j]存储a[i][j]的延长距离
        }
    }

    int q, l, r;
    cin >> q;
    while(q--)
    {
        cin >> l >> r;
        if(c[l] + l >= r)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}
Authur_gyc 发布了165 篇原创文章 · 获赞 22 · 访问量 2万+ 私信 关注

标签:cnt,777C,cin,int,Alyona,CodeForces,一列,printf,延伸
来源: https://blog.csdn.net/WHY995987477/article/details/104152130