codeforces 777C Alyona and Spreadsheet

题目链接:https://vjudge.net/problem/CodeForces-777C

题意:

给你一个n*m的矩阵,k个询问,每个询问有l,r,让你求在l-r行里面有没有一列可以满足从上到下为非递减数列。

思路:

预处理每一个点能到达的行的最大值,例如,如果第a[1][1] 最大能到达第四行,那么a[2][1],a[3][1],最大能到达的都是第四行。然后求出每一行中的最大值,即为该行能到达的最大行的值

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)	// 检查其中一个点
{
	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++)  // 一列一列的遍历
	{
		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;		// 直接跳到第tmpi行
			}
			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++)	// 求出每一行的最大值
		{
			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;
}
发布了238 篇原创文章 · 获赞 104 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/hpu2022/article/details/101478360