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("
");
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;
}