蚯蚓

谁说我不能喝 提交于 2019-12-03 20:07:14

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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!