[NOIp2016]蚯蚓 (队列)
#\(\color{red}{\mathcal{Description}}\)
这道题是个\(zz\)题
#\(\color{red}{\mathcal{Solution}}\)
我们考虑如何得部分分,即十分\(zz\)的\(\Theta((m+n)log(m+n))\),窝萌发现这个复杂度似乎可以接受,但是会爆是真的,所以每当这个时候我们就需要思考问题内部的单调性。我们发现其实对于两条蚯蚓\(A\)和\(B\),设它们的长度为\(L_A\)和\(L_B\),假设他们满足\(L_A < L_B\),那么他们都砍去\(p \times 100%\)后坑定会有\(L_{Br} > L_{Ar}\),\(L_{Bl} > L_{Al}\)……那么从技术层面来讲,他们都会加\(mq-q\)……所以最终来讲,当前大于之后也一定大于……所以用三个队列维护一下即可\(qwq\)
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 1000100
using namespace std ;
queue<int> q, q1, q2 ; int cnt, L, R ;
int now, H1, H2, H3 ; double U, V, P ;
int mark = 0, A[MAXN], N, M, H, T, i, Ans[MAXN << 3] ;
inline int qr(){
int k = 0 ; char c = getchar() ;
while (c < '0' || c > '9') c = getchar() ;
while (c <= '9' && c >= '0') k = (k << 1) + (k << 3) + c - 48, c = getchar() ;
return k ;
}
inline bool cmp(int J, int L){return J > L ;}
int main(){
cin >> N >> M >> H >> U >> V >> T ;
for (i = 1; i <= N; ++ i) A[i] = qr() ;
sort(A + 1, A + N + 1, cmp) ;
for (i = 1; i <= N; i ++) q.push(A[i]) ;
for (i = 1; i <= M; ++ i){
H1 = q.empty() ? -0x7fffffff : q.front(),
H2 = q1.empty() ? -0x7fffffff : q1.front(),
H3 = q2.empty() ? -0x7fffffff : q2.front() ;
if (H1 >= H2 && H1 >= H3) q.pop(), now = H1 ;
else if (H2 >= H1 && H2 >= H3) q1.pop(), now = H2 ;
else if (H3 >= H1 && H3 >= H2) q2.pop(), now = H3 ;
now += mark, mark += H ;
L = (double)now * U / V , R = now - L, L -= mark, R -= mark ;
q1.push(L), q2.push(R) ;
if (i % T == 0) printf("%d ", now) ;
}
putchar('\n') ;
while(!q.empty() || !q2.empty() || !q1.empty()){
H1 = q.empty() ? -0x7fffffff : q.front(),
H2 = q1.empty() ? -0x7fffffff : q1.front(),
H3 = q2.empty() ? -0x7fffffff : q2.front(), ++ cnt ;
if (H1 >= H2 && H1 >= H3) q.pop(), now = H1 ;
else if (H2 >= H1 && H2 >= H3) q1.pop(), now = H2 ;
else if (H3 >= H1 && H3 >= H2) q2.pop(), now = H3 ;
if (cnt % T == 0) printf("%d ", now + mark) ;
}
return 0 ;
}