NOIP 2016 蚯蚓
做法:
开三个队列,分别表示原始的蚯蚓,砍一刀后较大的一条,砍一刀后较小的一条。
我们发现这三个队列都具有单调性,所以开三个队列,然后每次从这三个队列的队首取最长的一条,就可以解决这个问题了。
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cmath> using namespace std; #define maxn 7000100 int n, m, q; int u, v; int t; double p; int cnt = 0; int a[maxn], b[maxn], c[maxn]; int ans1[maxn]; int ans2[maxn]; int tot1 = 1, tot2l = 1, tot2r = 0, tot3l = 1, tot3r = 0; bool cmp(int x, int y) { return x > y; } int main() { scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t); p = (double)u/v; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } sort(a + 1, a + n + 1, cmp); for(int i = 1; i <= m; i++) { int now = -2e9, pd = 0; if(tot1 <= n) { now = a[tot1], pd = 1; } if(tot2r != 0 && tot2l <= tot2r) { if(now < b[tot2l]) { now = b[tot2l]; pd = 2; } } if(tot3r != 0 && tot3l <= tot3r) { if(now < c[tot3l]) { now = c[tot3l]; pd = 3; } } ans1[i] = now + cnt; now += cnt; int x, y; x = (long long)now * u / v; y = now - x; b[++tot2r] = max(x, y) - q - cnt; c[++tot3r] = min(x, y) - q - cnt; if(pd == 1) tot1++; if(pd == 2) tot2l++; if(pd == 3) tot3l++; cnt += q; } for(int i = 1; i <= m / t; i++) printf("%d ", ans1[i * t]); printf("\n"); int tot = 0; while((tot2l <= tot2r) || (tot3l <= tot3r) || (tot1 <= n)) { int now = -2e9, pd = 0; if(tot1 <= n) { now = a[tot1], pd = 1; } if(tot2r != 0 && tot2l <= tot2r) { if(now < b[tot2l]) { now = b[tot2l]; pd = 2; } } if(tot3r != 0 && tot3l <= tot3r) { if(now < c[tot3l]) { now = c[tot3l]; pd = 3; } } if(!pd) break; ans2[++tot] = now + cnt; if(pd == 1) tot1++; if(pd == 2) tot2l++; if(pd == 3) tot3l++; } for(int i = 1; i <= (n + m) / t; i++) printf("%d ", ans2[i * t]); return 0; }