• [NOIP 2016] 蚯蚓


    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=4721

    [算法]

            首先,我们可以维护一个堆,堆中存放蚯蚓的长度,由于除当前蚯蚓其他的蚯蚓长度都要增加q,我们不妨将当前蚯蚓长度减去q,期望得分85pts

            进一步观察,我们发现,同一种切法,早切的蚯蚓一定比晚切的长,根据这个性质,维护三个单调队列,分别维护未被切割的蚯蚓长度,被切割过的蚯蚓长度中较长的那些的长度,被切割的蚯蚓长度中较短的那些的长度,时间复杂度O(M),可以通过所有数据

    [代码]

              注意为了避免精度误差,需使用long double类型,否则可能无法通过UOJ Extra Test

    #include<bits/stdc++.h>
    using namespace std;
    const long long INF = 1e18;
    const long long MAXN = 1e7;
    
    long long i,n,m,u,value,t,x,y,mx,pos,v;
    long long head[10],tail[10],ans1[MAXN],ans2[MAXN];
    long long q[3][MAXN];
    
    template <typename T> inline void read(T &x)
    {
            long long f = 1; x = 0;
            char c = getchar();
            for (; !isdigit(c); c = getchar())
            {
                    if (c == '-') f = -f;
            }
            for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
            x *= f;
    }
    
    int main() 
    {
            
            read(n); read(m); read(value); read(u); read(v); read(t);
            for (i = 1; i <= n; i++)
            {
                    read(x);
                    q[0][++tail[0]] = x; 
            } 
            head[0] = head[1] = head[2] = 1;
            sort(q[0] + 1,q[0] + tail[0] + 1,greater<long long>());
            for (i = 1; i <= m; i++)
            {
                    mx = -INF;
                    if (head[0] <= tail[0] && q[0][head[0]] > mx)
                    {
                            mx = q[0][head[0]];
                            pos = 0;
                    }
                    if (head[1] <= tail[1] && q[1][head[1]] > mx)
                    {
                            mx = q[1][head[1]];
                            pos = 1;
                    }
                    if (head[2] <= tail[2] && q[2][head[2]] > mx)
                    {
                            mx = q[2][head[2]];
                            pos = 2;
                    }
                    ans1[i] = mx + (i - 1) * value;
                    head[pos]++;
                    x = (long long)((mx + (i - 1) * value) * (long double)1.0 * u / v) - i * value;
                    y = mx + (i - 1) * value - (long long)((mx + (i - 1) * value) * (long double)1.0 * u / v) - i * value;
                    q[1][++tail[1]] = max(x,y);
                    q[2][++tail[2]] = min(x,y);
            }
            for (i = 1; i * t <= m; i++) printf("%lld ",ans1[i * t]);
            printf("
    ");
            for (i = 1; i <= n + m; i++) 
            {
                    mx = -INF;
                    if (head[0] <= tail[0] && q[0][head[0]] > mx)
                    {
                            mx = q[0][head[0]];
                            pos = 0;
                    }
                    if (head[1] <= tail[1] && q[1][head[1]] > mx)
                    {
                            mx = q[1][head[1]];
                            pos = 1;
                    }
                    if (head[2] <= tail[2] && q[2][head[2]] > mx)
                    {
                            mx = q[2][head[2]];
                            pos = 2;
                    }
                    ans2[i] = mx + m * value;
                    head[pos]++;
            }
            for (i = 1; i * t <= n + m; i++) printf("%lld ",ans2[i * t]);
            printf("
    ");
            
            return 0;
        
    }
  • 相关阅读:
    数组中找出最小的K个数
    温故而知新---Java(一)
    写一手简洁的代码
    同步IO与同步非阻塞IO的理解
    旋转打印矩阵
    求仅出现一次的最早字符
    spring 自定义schema 加载异常 White spaces are required between publicId and systemId.
    Java位运算知识点整理
    Idea 插件开发之DubboInvoke实践
    pinpoint插件开发实践
  • 原文地址:https://www.cnblogs.com/evenbao/p/9470473.html
Copyright © 2020-2023  润新知