1. 程式人生 > >P2827 蚯蚓

P2827 蚯蚓

const ans floor 排序 printf code ont 基本 efi

暴力出奇跡!!!

昨晚很積極地拿手機看這道題的題面,還挺易懂的。

然後寫了第二發程序,用優先隊列再弄個delta輕輕松松85pts。。。

要是過幾天考試能像這樣該多好啊。。。


顯然那個人挑出所有蚯蚓的最長的,就是堆的基本操作了。

然後想到沒有挑出來的蚯蚓是會長長的,但是他們已經在堆裏面,用優先隊列不可能去修改他們啊!

其實直接維護個變量就可以了。

加新的蚯蚓就要記得減掉這個delta,把蚯蚓拿出來就記得加上這個delta,然後就沒問題了。

所以輕松地拿到85pts。。。


為什麽不能滿分?因為這個\(m\)太大了。

看了題解才知道,這道題還有隱含的單調性:先被切的蚯蚓,長度肯定比後被切的蚯蚓長!

可以很感性地理解。

然後就可以用3個隊列(算是單調隊列),第一個裝原蚯蚓,第二個裝被切的短的蚯蚓,第三個裝被切的長的蚯蚓。

每一次就從3個隊頭找出最大值,切掉他,分別扔進第二和第三個隊列。

第二問也照著做就是了,沒有什麽思維難度。


幾個小細節:

因為這個delta會越來越大,所以隊列中的新蚯蚓的值會越來越小,所以最大值初始化要是負INF而不能是-1。

蚯蚓進第一個隊列的時候記得從大到小排序啊!

代碼:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#define ll long long
const int maxn = 100005;
const ll INF = 0x3f3f3f3f3f;
ll a[maxn];

std::queue<ll> qq[3];
ll delta = 0;
ll n, m, q, u, v, t;
double p;
bool cmp(ll a, ll b)
{
    return a > b;
}
ll read()
{
    ll ans = 0, s = 1;
    char ch = getchar();
    while(ch > ‘9‘ || ch < ‘0‘){ if(ch == ‘-‘) s = -1; ch = getchar(); }
    while(ch >= ‘0‘ && ch <= ‘9‘) ans = (ans << 3) + (ans << 1) + ch - ‘0‘, ch = getchar();
    return s * ans;
}
int main()
{
    n = read(), m = read(), q = read(), u = read(), v = read(), t = read();
    p = (double)(u) / (double)(v);
    for(int i = 1; i <= n; i++) a[i] = read();
    std::sort(a + 1, a + n + 1, cmp);
    for(int i = 1; i <= n; i++) qq[0].push(a[i]);
    bool first = true;
    for(int i = 1; i <= m; i++)
    {
        ll maxv = -INF, where = -1;
        for(int j = 0; j < 3; j++)
        {
            if(!qq[j].empty() && qq[j].front() > maxv) where = j, maxv = qq[j].front();
        }
        ll x = qq[where].front() + delta; qq[where].pop();
        if(i % t == 0)
        {
            if(first) printf("%lld", x), first = false;
            else printf(" %lld", x);
        }
        ll one = floor(p * x);
        ll other = x - one;
        if(one > other) std::swap(one, other);
        delta += q;
        qq[1].push(one - delta);
        qq[2].push(other - delta);
    }
    printf("\n");
    first = true;
    for(int i = 1; i <= n + m; i++)
    {
        ll maxv = -INF, where = -1;
        for(int j = 0; j < 3; j++)
        {
            if(!qq[j].empty() && qq[j].front() > maxv) where = j, maxv = qq[j].front();
        }
        ll x = qq[where].front() + delta; qq[where].pop();
        if(i % t == 0)
        {
            if(first) printf("%lld", x), first = false;
            else printf(" %lld", x);
        }
    }
    printf("\n");
    return 0;
}

P2827 蚯蚓