BZOJ4721: [Noip2016]蚯蚓

一眼是个优先队列暴力?甚至好像 mlogn 没有很大?

不存在的哪有能让你 1e8 跑满还不 T 的出题人

其实它是个...结论题?甚至还是个不写一写我根本无法想出来的结论

因为先切最大的

所以先切的分出来的也一定比后切的分出来的大

设 a > b

a 先分为了: a * p, a * (p - 1)

经过 t 时间后,b 被分为了: (b + t) * p, (b + t) * (p - 1)

且此时 a 分成的两段长度为: a * p + t, a * (p - 1) + t

拆一下式子发现 : a * p + t > (b + t) * p , 另一段同理

所以我们就这样发现这个东西是有单调性的,可以用队列乱搞

开三个队列

一个是存没有切过的蚯蚓

一个是存切为 px 的蚯蚓

一个是存切为 (1 - p) * x 的蚯蚓

 只要保证一开始且的顺序是有序的就行了,所以预先排个序就好了


代码:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;

const int MAXN = 100005, MAXM = 7000005;

int n, m, q, u, v, t;
int gg[MAXN], que[3][MAXN + MAXM], hd[3], tl[3];
double p;
priority_queue<int> res;

inline int rd() {
	register int x = 0;
	register char c = getchar();
	while(!isdigit(c)) c = getchar();
	while(isdigit(c)) {
		x = x * 10 + (c ^ 48);
		c = getchar();
	}
	return x;
}

int main() {
	n = rd(); m = rd(); q = rd(); u = rd(); v = rd(); t = rd();
	p = (double)u / (double)v;
	for(int i = 1; i <= n; ++i) gg[i] = rd();
	sort(gg + 1, gg + n + 1);
	hd[0] = hd[1] = hd[2] = 1;
	for(int i = n; i >= 1; --i) que[0][++tl[0]] = gg[i];
	int cnt = 0, maxn, maxp, p1, p2, cur, tot = 0;
	while(m--) {
		++cnt;
		maxn = 0xcfcfcfcf;
		if(hd[0] <= tl[0] && que[0][hd[0]] > maxn) maxn = que[0][hd[0]], maxp = 0;
		if(hd[1] <= tl[1] && que[1][hd[1]] > maxn) maxn = que[1][hd[1]], maxp = 1;
		if(hd[2] <= tl[2] && que[2][hd[2]] > maxn) maxn = que[2][hd[2]], maxp = 2;
		cur = que[maxp][hd[maxp]] + tot; ++hd[maxp];
		p1 = (int)floor((double)cur * p);
		p2 = cur - p1;
		tot += q;
		que[1][++tl[1]] = p1 - tot;
		que[2][++tl[2]] = p2 - tot;
		if(cnt == t) {
			printf("%d ", cur);
			cnt = 0;
		}
	}puts("");
	cnt = 0;
	while(hd[0] <= tl[0] || hd[1] <= tl[1] || hd[2] <= tl[2]) {
		++cnt;
		maxn = 0xcfcfcfcf;
		if(hd[0] <= tl[0] && que[0][hd[0]] > maxn) maxn = que[0][hd[0]], maxp = 0;
		if(hd[1] <= tl[1] && que[1][hd[1]] > maxn) maxn = que[1][hd[1]], maxp = 1;
		if(hd[2] <= tl[2] && que[2][hd[2]] > maxn) maxn = que[2][hd[2]], maxp = 2;
		cur = que[maxp][hd[maxp]] + tot; ++hd[maxp];
		if(cnt == t) {
			printf("%d ", cur);
			cnt = 0;
		}
	}puts("");
	return 0;
}

  

 

posted @ 2018-09-06 21:23  EvalonXing  阅读(123)  评论(0编辑  收藏  举报