【NOIP 2016 提高组】蚯蚓

Description

【NOIP 2016 提高组】蚯蚓_第1张图片

Solution

这题算是一道结论题,
先来想一下,当q=0时,很显然有结论:
1. 对于所有没有被切过的蚯蚓,一定是越切越短。
2. 对于被切开的两段,随着时间的增加,新切的两段分别都是越来越短。

也就是说,只要开3个队列,每次取出最大值即可,

那么当q>0时,我们发现,以上的性质同样符合,所以只要多维护一个时间即可。

复杂度: O(n)

Code

#include 
#include 
#include 
#include 
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef double db;
const int N=7000500,INF=2147483640;
int n,m,ans,m1,sc,Q,W;
db P;
int s[3],ti[3];
struct qqww
{
    int v,t,n;
}t,d[3][N];
bool operator <(qqww q,qqww w){return q.v-q.t*m1*m1;}
qqww max(qqww q,qqww w){return (q.v-q.t*m1>w.v-w.t*m1)?q:w;}
bool PX(qqww q,qqww w){return w<q;}
int main()
{
    freopen("earthworm.in","r",stdin);
    freopen("earthworm.out","w",stdout);
    int q,w;
    scanf("%d%d%d%d%d%d",&n,&m,&m1,&Q,&W,&sc);
    fo(i,1,n)scanf("%d",&d[0][i].v);
    sort(d[0]+1,d[0]+1+n,PX);
    s[0]=s[1]=s[2]=1;ti[0]=n;
    fo(i,1,m)
    {
        t.v=-INF/2;
        fo(j,0,2)if(s[j]<=ti[j]&&ts[j]])t=d[j][s[j]],t.n=j;
        s[t.n]++;
        t.v+=(i-t.t-1)*m1;t.t=i;
        if(i%sc==0)printf("%d ",t.v);
        q=(long double)t.v*Q/W+1e-6;w=t.v-q;
        t.v=q;
        d[1][++ti[1]]=t;
        t.v=w;
        d[2][++ti[2]]=t;
    }
    printf("\n");
    fo(i,1,n+m)
    {
        t.v=-INF/2;
        fo(j,0,2)if(s[j]<=ti[j]&&ts[j]])t=d[j][s[j]],t.n=j;
        s[t.n]++;
        t.v+=(m-t.t)*m1;
        if(i%sc==0)printf("%d ",t.v);
    }
    return 0;
}

你可能感兴趣的:(正式赛)