【LA4726】Average【斜率优化】【单调队列】

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=30&page=show_problem&problem=2727

题意:

给出一个01串,问平均值最大,且长度至少为L的区间端点。


大白上的题,写了之后发现是论文题...见周源《浅谈数形结合思想在信息学竞赛中的应用》


/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef double DB;

const int maxn = 100005, maxq = maxn;

int n, L, sum[maxn], q[maxq];
char str[maxn];

inline int y(int a, int b) {
	return sum[a] - sum[b];
}

inline int x(int a, int b) {
	return a - b;
}

int main() {
	int T; scanf("%d", &T);
	while(T--) {
		scanf("%d%d%s", &n, &L, str + 1);
		for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + (str[i] == '1');

		int h = 0, t = -1, ansl = 0, ansr = L;
		DB ans = sum[L] /(DB) L;
		for(int i = L; i <= n; i++) {
			int u = i - L;
			for(; h < t && y(u, q[t]) * x(u, q[t - 1]) <= y(u, q[t - 1]) * x(u, q[t]); t--);
			q[++t] = u;
			for(; h < t && y(i, q[h]) * x(i, q[h + 1]) <= y(i, q[h + 1]) * x(i, q[h]); h++);
			DB res = y(i, q[h]) /(DB) x(i, q[h]);
			if(res > ans) {
				ans = res;
				ansl = q[h]; ansr = i;
			} else if(res == ans && ansr - ansl > i - q[h]) {
				ansl = q[h]; ansr = i;
			}
		}
	
		printf("%d %d\n", ansl + 1, ansr);
	}
	return 0;
}


你可能感兴趣的:(【LA4726】Average【斜率优化】【单调队列】)