题解 P2827 【蚯蚓】
思路:
我们可以想一下,对于每一秒除了被切的哪一个所有的蚯蚓都增长Q米,我们来维护3个队列,队列1表示最开始的蚯蚓,队列2表示每一次被切的蚯蚓被分开的较长的那一部分,队列3表示每一次被切的蚯蚓被分开的较短的那一部分。
我们先把原序列排序,因为不管怎么切,先被切的蚯蚓分成的两部分一定比后切的蚯蚓分成的两部分大(较大的部分和较大的部分比较,较小的部分和较小的部分比较),所以我们可以省去每一秒增加每只蚯蚓的长度这个操作,转换成在查询砍那只蚯蚓时,把增加的长度算到蚯蚓的总长度上。
寻找每次砍哪一只蚯蚓就是在队列1、队列2、队列3的队头找一个算上增加的长度最大的蚯蚓,之后把他出队,切开的两部分分别进入队2、队3。
对于增量的计算我们可以按照蚯蚓在队列中的标号,因为队列1中的蚯蚓直到被切是一直处于一种增长状态,所以直接加上(当前时间-1) \* Q就可以了,而对于队列2和队列3的蚯蚓,他的增长是从被切掉那一刻的下一秒开始的,所以他的增长量则是(当前时间-1-被切割的时间)\*Q。
统计答案的时候把三个队列合并,排序输出就可以了。
代码如下
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN = 1e7;
inline int read(){
int w = 1, data = 0; char ch = 0;
while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(ch >= '0' && ch <= '9') data = data * 10 + ch - '0', ch = getchar();
return w * data;
}
int n, Q, m, T, h[10], t[10], tmp;
double u, v, p;
int q[4][MAXN], ans[MAXN];
inline void find(int x){
int num = 0, sum = 0;
for(int i = 1; i <= 3; i++){
if(i == 1 && q[i][h[i]] + x * Q > sum && h[i] < t[i]) num = i, sum = q[i][h[i]] + x * Q;
else if(q[i][h[i]] + (x-h[i])*Q > sum && h[i] < t[i]) num = i, sum = q[i][h[i]] + (x-h[i])*Q;
}
ans[x+1] = sum; tmp = sum; q[num][h[num]++];
}
int lxz[MAXN];
void Print_Ans(){
int num = 0;
for(int i = T, tot = 1; i <= m && tot <= m/T; i += T, tot++)
printf("%d ",ans[i]);
printf("\n");
for(int i = 1; i <= 3; i++){
for(int j = h[i]; j < t[i]; j++){
if(i == 1 && h[i] < t[i]) lxz[++num] = q[i][j] + (m) * Q;
else if(h[i] < t[i]) lxz[++num] = q[i][j] + (m-j)*Q;
}
}
sort(lxz+1, lxz+num+1, greater<int>());
for(int i = T, tot = 1; i <= num && tot <= (n+m)/T; i += T, tot++)
printf("%d ",lxz[i]);
}
int main(){
scanf("%d%d%d%lf%lf%d", &n, &m, &Q, &u, &v, &T);
p = u / v;
for(int i = 1; i <= 3; i++) h[i] = t[i] = 1;
for(int i = 1; i <= n; i++) q[1][i] = read(), t[1]++;
sort(q[1]+h[1], q[1]+t[1], greater<int>());
for(int i = 1; i <= m; i++){
find(i-1);
double a = floor(tmp * p), b = tmp - a;
if(a < b) swap(a, b);
q[2][t[2]++] = a; q[3][t[3]++] = b;
}
Print_Ans();
return 0;
}