1. 程式人生 > >[luoguP2827] 蚯蚓(堆?隊列!)

[luoguP2827] 蚯蚓(堆?隊列!)

排序 fine turn efi targe blank nbsp eof dig

傳送門

35分做法

用堆來取最大值,暴力更新其余數的值。

65~85分做法

還是用堆來取最大值,其余的數增加可以變成新切開的兩個數減少,最後統一加上一個數。

#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define LL long long

LL q, u, v;
int n, m, t;

std::priority_queue <LL> Q;

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
    for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
    return x * f;
}

int main()
{
    int i;
    LL x, y;
    n = read();
    m = read();
    q = read();
    u = read();
    v = read();
    t = read();
    for(i = 1; i <= n; i++)
    {
        x = read();
        Q.push(x);
    }
    for(i = 1; i <= m; i++)
    {
        if(i % t == 0) printf("%lld ", (LL)Q.top() + (i - 1) * q);
        x = (LL)(Q.top() + (i - 1) * q) * u / v;
        y = (LL)Q.top() + (i - 1) * q - x;
        Q.pop();
        Q.push(x - i * q);
        Q.push(y - i * q);
    }
    puts("");
    for(i = 1; i <= n + m; i++)
    {
        if(i % t == 0) printf("%lld ", (LL)Q.top() + m * q);
        Q.pop();
    }
    return 0;
}

100分做法

先排序。

將最大的切成兩個小的分別放到另兩個隊列b和c裏。

取最大值的話就從這3個隊列的隊頭找最大的,切完後再放回b和c隊列隊尾。

這樣b和c始終是單調遞減。

同樣,其余的增加可以換成切出來的另兩個減少。

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 7000003
#define LL long long
#define max(x, y) ((x) > (y) ? (x) : (y))
#define Max(x, y, z) ((x) > max(y, z) ? (x) : max(y, z))

LL q, u, v, a[N], b[N], c[N];
int n, m, t, t1, t2 = 1, t3 = 1, cnt;

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
	return x * f;
}

int main()
{
	int i;
	LL x, y;
	t1 = n = read();
	m = read();
	q = read();
	u = read();
	v = read();
	t = read();
	a[0] = -(~(1 << 31));
	memset(b, -127 / 3, sizeof(b));
	memset(c, -127 / 3, sizeof(c));
	for(i = 1; i <= n; i++) a[i] = read();
	std::sort(a + 1, a + n + 1);
	for(i = 1; i <= m; i++)
	{
		if(i % t == 0) printf("%lld ", Max(a[t1], b[t2], c[t3]) + (i - 1) * q);
		if(Max(a[t1], b[t2], c[t3]) == a[t1] && t1 >= 1)
		{
			cnt++;
			x = (a[t1] + (i - 1) * q) * u / v;
			y = a[t1] + (i - 1) * q - x;
			b[cnt] = x - i * q;
			c[cnt] = y - i * q;
			t1--;
		}
		else if(Max(a[t1], b[t2], c[t3]) == b[t2] && t2 <= cnt)
		{
			cnt++;
			x = (b[t2] + (i - 1) * q) * u / v;
			y = b[t2] + (i - 1) * q - x;
			b[cnt] = x - i * q;
			c[cnt] = y - i * q;
			t2++;
		}
		else
		{
			cnt++;
			x = (c[t3] + (i - 1) * q) * u / v;
			y = c[t3] + (i - 1) * q - x;
			b[cnt] = x - i * q;
			c[cnt] = y - i * q;
			t3++;
		}
	}
	puts("");
	for(i = 1; i <= n + m; i++)
	{
		if(i % t == 0) printf("%lld ", Max(a[t1], b[t2], c[t3]) + m * q);
		if(Max(a[t1], b[t2], c[t3]) == a[t1] && t1 >= 1) t1--;
		else if(Max(a[t1], b[t2], c[t3]) == b[t2] && t2 <= cnt) t2++;
		else t3++; 
	}
	return 0;
}

  

由這個題可見還是得多挖掘題目給出的性質。

[luoguP2827] 蚯蚓(堆?隊列!)