题目描述
输入格式
输出格式
输出到文件 earthworm.out
第一行输出[m/t]个整数,按时间顺序,依次输出第t秒,第2t秒,第3t秒……被切断蚯蚓(在被切断前)的长度。
样例数据
样例输入
输入样例#1:
3 7 1 1 3 1
3 3 2
输入样例#2:
3 7 1 1 3 2
3 3 2
输入样例#3:
3 7 1 1 3 9
3 3 2
样例输出
输出样例#1:
3 4 4 4 5 5 6
6 6 6 5 5 4 4 3 2 2
输出样例#2:
4 4 5
6 5 4 3 2
输出样例#3:
//空行
2
说明
【样例解释1】
在神刀手到来前:3只蚯蚓的长度为3,3,2。
1秒后:一只长度为3的蚯蚓被切成了两只长度分别为1和2的蚯蚓,其余蚯蚓的长度增加了1。最终4只蚯蚓的长度分别为(1,2),4,3。括号表示这个位置刚刚有一只蚯蚓被切断
2秒后:一只长度为4的蚯蚓被切成了1和3。5只蚯蚓的长度分别为:2,3,(1,3),4。
3秒后:一只长度为4的蚯蚓被切断。6只蚯蚓的长度分别为:3,4,2,4,(1,3)。
4秒后:一只长度为4的蚯蚓被切断。7只蚯蚓的长度分别为:4,(1,3),3,5,2,4。
5秒后:一只长度为5的蚯蚓被切断。8只蚯蚓的长度分别为:5,2,4,4,(1,4),3,5。
6秒后:一只长度为5的蚯蚓被切断。9只蚯蚓的长度分别为:(1,4),3,5,5,2,5,4,6。
7秒后:一只长度为6的蚯蚓被切断。10只蚯蚓的长度分别为:2,5,4,6,6,3,6,5,(2,4)。所以,7秒内被切断的蚯蚓的长度依次为3,4,4,4,5,5,6。7秒后,所有蚯蚓长度从大到小排序为6,6,6,5,5,4,4,3,2,2
【样例解释2】
这个数据中只有t=2与上个数据不同。只需在每行都改为每两个数输出一个数即可。
虽然第一行最后有一个6没有被输出,但是第二行仍然要重新从第二个数再开始输出。
【样例解释3】
这个数据中只有t=9与上个数据不同。
注意第一行没有数要输出,但也要输出一个空行。
题目分析
正常想法:堆+偏移(这个写起来比正解还麻烦。。。)
预计分数:80分
正解:
开三个队列,第一个队列储存没有被切得蚯蚓,第二个队列储存被切过得前一半蚯蚓,第三个队列储存被切过的后一半蚯蚓。
事先将第一个队列从大到小排序,便可以保证所有队列均有序(想一想,为什么?)
每次从三个队列中取出一个最大的切掉,同时将偏移量delta加着走,当然要保证队列里的元素是减了delta的。
为什么需要引入偏移量delta呢?因为我们要保持队列有序,如果手动排序就nlogn了,就成了暴力,因此需要delta来间接维护队列。
注意要开long long!
源代码
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
bool cmp(long long a,long long b) {
return a>b;
}
int n,m,q,u,v,t,cnt=0;
long long a[8000005],Delta=0;
deque<long long>Q[4];
int main() {
n=Get_Int();
m=Get_Int();
q=Get_Int();
u=Get_Int();
v=Get_Int();
t=Get_Int();
for(int i=1; i<=n; i++)a[i]=Get_Int();
sort(a+1,a+n+1,cmp);
for(int i=1; i<=n; i++)Q[1].push_back(a[i]);
for(int i=1; i<=m; i++) {
long long Max=-1e10,maxl;
for(int j=1; j<=3; j++)
if(!Q[j].empty()&&Q[j].front()>Max) {
Max=Q[j].front();
maxl=j;
}
Q[maxl].pop_front();
Max+=Delta;
if(i%t==0)printf("%lld ",Max);
Delta+=q;
long long Left=Max*u/v,Right=Max-Left;
Q[2].push_back(Left-Delta);
Q[3].push_back(Right-Delta);
}
putchar('\n');
while(!Q[1].empty()||!Q[2].empty()||!Q[3].empty()) {
cnt++;
long long Max=-1e10,maxl;
for(int i=1; i<=3; i++)
if(!Q[i].empty()&&Q[i].front()>Max) {
Max=Q[i].front();
maxl=i;
}
Max+=Delta;
if(cnt%t==0)printf("%lld ",Max);
Q[maxl].pop_front();
}
return 0;
}