蚯蚓

原题链接:https://www.luogu.org/problem/show?pid=2827

原本拿来练习堆,但我发现其实堆并不是正解。。。。普通队列就可以做的。

参考了noip老师的思路。喜闻乐见的三队列大众做法。

根据题目大意,我们有n个非负整数和m次操作,每次操作移除一个最大的s,剩下的数每个增加q,再加入两个新数floor(p*x) 和 x - floor(p*x)。

第一行按时间顺序输出被切断蚯蚓的长度,第二行输出m秒后蚯蚓的长度。

做法还是很简单的,首先对长度排序,然后全部压入队列a。

第一问,枚举m次操作,记录一个now时间点,同时更新当前最大值x,有一个getmax()函数取三队列当中的最大元素,加上 q * (i-1) 就是当前最大值x。发现了now == t也就是符合输出条件才可以输出。与此同时由于分割,需要更新b队列和c队列,也就是同时维护切成的两段。

有一个细节,更新b和c队列时乘了一个1ll,这不是什么奇怪的东西,这就是1,只不过是为了防止溢出,把结果强制转了long long。

然后敲一个回车开始处理第二问。

第二问依然是需要now来作为时间点,当其到达t时清零并输出。

参考代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <queue>
 6 #define maxn 7100010
 7 #define INF 2147483647
 8 #define check cout << "ok" << endl;
 9 using namespace std;
10 int n,m,q,u,v,t;
11 int len[maxn];
12 queue<int> a,b,c;
13 inline int read(){
14     int num = 0;
15     char c;
16     bool flag = false;
17     while ((c = getchar()) == ' ' || c == '\n' || c == '\r');
18     if (c == '-')
19         flag = true;
20     else
21         num = c - '0';
22     while (isdigit(c = getchar()))
23         num = num * 10 + c - '0';
24     return (flag ? -1 : 1) * num;
25 }
26 inline int getmax(void){
27     int ans = INF * (-1);
28     int pos = 0;
29     if (a.size() && a.front() > ans){
30         ans = a.front();
31         pos = 1;
32     }
33     if (b.size() && b.front() > ans){
34         ans = b.front();
35         pos = 2;
36     }
37     if (c.size() && c.front() > ans){
38         ans = c.front();
39         pos = 3;
40     }
41     switch(pos){
42         case 1:
43             a.pop();
44             break;
45         case 2:
46             b.pop();
47             break;
48         case 3:
49             c.pop();
50             break;
51     }
52     return ans;
53 }
54 
55 int main(){
56     n = read();m = read();q = read();
57     u = read();v = read();t = read();
58     for (register int i=1;i<=n;i++)
59         len[i] = read();
60     sort(len + 1,len + n + 1);
61     for (register int i=n;i;i--)
62         a.push(len[i]);
63 
64     for (register int i=1,now = 0;i<=m;i++){
65         int x = getmax() + q * (i-1);
66         now++;
67         if (now == t)
68             now = 0;
69         if (!now){
70             printf("%d ",x);
71         }
72         b.push(x - x *1ll* u/v - q*i);
73         c.push(x * 1ll * u/v - q*i);
74     }
75     putchar('\n');
76     int now = 0;
77     while (a.size() || b.size() || c.size()){
78         int x = getmax();
79         now++;
80         if (now == t)
81             now = 0;
82         if (!now){
83             printf("%d ", x + q * m);
84         }
85     }
86     return 0;
87 }

 

posted @ 2017-10-22 21:33  ShawnZhou_Aether  阅读(200)  评论(2编辑  收藏  举报