蚯蚓

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;
}
原文地址:https://www.cnblogs.com/Akaina/p/11806054.html