1. 程式人生 > >[NOIP2016]蚯蚓 亂搞

[NOIP2016]蚯蚓 亂搞

Description 你有n個線段,每一秒你要拿出來最長的一個線段切成兩段長度為pu\lfloor{p*u}\rfloorupuu-\lfloor{p*u}\rfloor兩段(其中u是線段長,p是一個大於0小於1的實數)沒被切的線段長度加q。問和第k秒的切割線段切割前的長度和m秒後的n+m條線段的長度。

Sample Input 3 7 1 1 3 1 3 3 2

Sample Output 3 4 4 4 5 5 6 6 6 6 5 5 4 4 3 2 2

我們開三個序列維護。 第一個序列存原數,第二個序列存pu\lfloor{p*u}\rfloor

,第三個序列存upuu-\lfloor{p*u}\rfloor。 每次取三個佇列隊頭最大值即可,易證不說了。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;
int _min(int x, int y) {return x < y ? x : y;}
int _max(int x, int y) {return x > y ? x : y;}
int read() {
	int s = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
	return s * f;
}
void put(int x) {
	if(x == 0) {putchar('0'); return ;}
    int num = 0; char c[15];
    while(x) c[++num] = (x % 10) + '0', x /= 10;
    while(num) putchar(c[num--]);
}

int len, a[110000];
int Q[3][7100001], l[3], r[3];

int main() {
	int n = read(), m = read(), q = read(), u = read(), v = read(), t = read();
	double p = (double)u / v;
	for(int i = 1; i <= n; i++) a[i] = read();
	sort(a + 1, a + n + 1); l[0] = 1, r[0] = n;
	l[1] = 1, r[1] = 0, l[2] = 1, r[2] = 0;
	for(int i = 1; i <= n; i++) Q[0][n - i + 1] = a[i];
	for(int i = 1; i <= m; i++) {
		int h1 = -2147483647, h2 = -2147483647, h3 = -2147483647;
		if(l[0] <= r[0]) h1 = Q[0][l[0]];
		if(l[1] <= r[1]) h2 = Q[1][l[1]];
		if(l[2] <= r[2]) h3 = Q[2][l[2]];
		if(h1 >= h2 && h1 >= h3) {
			int o = h1 + (i - 1) * q;
			if(i % t == 0) put(o);
			++l[0]; int hh = int(o * p);
			Q[1][++r[1]] = hh - i * q, Q[2][++r[2]] = o - hh - i * q;
		} else if(h2 >= h1 && h2 >= h3) {
			int o = h2 + (i - 1) * q;
			if(i % t == 0) put(o);
			++l[1]; int hh = int(o * p);
			Q[1][++r[1]] = hh - i * q, Q[2][++r[2]] = o - hh - i * q;
		} else {
			int o = h3 + (i - 1) * q;
			if(i % t == 0) put(o);
			++l[2]; int hh = int(o * p);
			Q[1][++r[1]] = hh - i * q, Q[2][++r[2]] = o - hh - i * q;
		} if(i % t == 0 && i != m / t * t) putchar(' ');
	} puts("");
	for(int i = 1; i <= n + m; i++) {
		int h1 = -2147483647, h2 = -2147483647, h3 = -2147483647;
		if(l[0] <= r[0]) h1 = Q[0][l[0]];
		if(l[1] <= r[1]) h2 = Q[1][l[1]];
		if(l[2] <= r[2]) h3 = Q[2][l[2]];
		if(h1 >= h2 && h1 >= h3) {
			if(i % t == 0) put(h1 + m * q);
			++l[0];
		} else if(h2 >= h1 && h2 >= h3) {
			if(i % t == 0) put(h2 + m * q);
			++l[1];
		} else {
			if(i % t == 0) put(h3 + m * q);
			++l[2];
		} if(i % t == 0 && i != (n + m) / t * t) putchar(' ');
	}
	return 0;
}