P10059 Choose(st表)


本题要构建两个st表,一个储存区间最大值,一个储存区间最小值,我们的思路是先构建k个最长的的子序列

这样就可以求出最小的极差的最大值(有点绕口),这个怎么理解呢,因为当你扩大区间时,区间的极差只可能比原来更大,因为如果扩进了一个大值那么极差不变,如果扩进了一个比原先区间最小值还小的值的话,极差就会变大,所以最开始要求最小极差的最大值,我们应该让这k个区间尽可能的大,每个区间的长度应该为n-k+1;,然后二分查找一步步缩小区间,然后从一遍历满足极差>=x的区间,在遍历的过程中如果s==k,就不需要再遍历了,直接break

#include<iostream>
#include<set>
#include<map>
#include<algorithm>
#include<vector>
#include<cmath>
#include<climits>
#define int long long
const int N = 1e6;
using namespace std;
char* p1, * p2, buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int read()
{
	int x = 0, f = 1;
	char ch = nc();
	while (ch < 48 || ch>57)
	{
		if (ch == '-')
			f = -1;
		ch = nc();
	}
	while (ch >= 48 && ch <= 57)
		x = x * 10 + ch - 48, ch = nc();
	return x * f;
}
int a[N][20], b[N][20];
int n, k;
int query(int left, int right) {
	int len = log2(right - left + 1);
	int maxx = max(a[left][len], a[right - (1 << len)+1][len]);
	int minn = min(b[left][len], b[right - (1 << len)+1][len]);
	return maxx - minn;
}
int find(int x) {
	int begin = 1, end = n - k+1;
	int p = 0;
	while (begin <= end) {
		int mid = (begin + end) >> 1;
		int s = 0;
		for (int i = 1; i <= n - mid + 1; i++) {
			if (query(i, i + mid - 1) >= x)s++;
			if (s == k)break;
		}
		if (s == k)end = mid - 1, p = mid;
		else begin = mid + 1;
	}
	return p;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int T;
	cin >> T;
	while (T--) {
		
		cin >> n >> k;
		for (int i = 1; i <= n; i++) {
			cin >> a[i][0];
			b[i][0] = a[i][0];
		}
		int len = log2(n - 1 + 1);
		for (int i = 1; i <= len; i++) {
			for (int j = 1; j + (1 << i) - 1 <= n; j++) {
				a[j][i] = max(a[j][i - 1], a[j + (1 << (i - 1))][i - 1]);
				b[j][i] = min(b[j][i - 1], b[j + (1 << (i - 1))][i - 1]);
			}
		}
		int x = INT_MAX;
		for (int i = 1; i <= k; i++) {
			x = min(x, query(i, n - k + i));
		}
		cout << x << " " << find(x) << endl;
	}
	
	return 0;
}
posted @   郭轩均  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示