蚯蚓
原题链接: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 }
一切无法杀死我的,都将使我变得更加强大。