[NOIP2016] earthworms (monotonicity promiscuity)

topic

link

Thinking

The simplest idea is to use the heap to maintain direct affirmation, each taking a maximum of that, cut into two parts back into the heap (As with all earthworms plus \ (q \) , it can be seen as a new generation of earthworms minus \ (Time * Q \) , and finally back to plus, where \ (Time \) ie a few seconds), but this way is done \ (O (n + m) log (n + m) \) , over can not

After the analysis can be found monotonic, i.e. if the two portions are cut out into an array which, respectively monotonically decreasing

Proof is very simple, let the first cut of earthworms length \ (len1 \) , after the cut in the cut \ (len1 \) this time length \ (len2 \) , then there \ (len2 \) \ (\ Leq \) \ (LEN1 \) , which length growth time is only cut when, i.e. they increase the amount are equal, then there is \ (LEN2 + C \) \ (\ Leq \) \ (LEN1 + C \) constant set up

Therefore divide them into three arrays (queues), respectively, the initial deposit earthworms, (after cutting knife) a first, a second, the initial ordering may earthworms descending order so that the first array, to cut out after earthworms into the queue behind such that the two arrays can also meet the descending order, i.e., taking the maximum of the maximum value from the earthworm three HOL queue

For the second question, the three queue to merge sort

Time complexity is \ (O (nlogn + m) \)

#include<bits/stdc++.h>
#define N 100005
#define M 7000005
using namespace std;
int n,m,q,u,v,t;
int a[3][M],top[3];
int b[N+M],c[N+M];

template <class T>
void read(T &x)
{
    char c;int sign=1;
    while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    while((c=getchar())>='0'&&c<='9') x=x*10+c-48; x*=sign;
}
bool cmp(int a,int b) {return a>b;} 
int main()
{
    read(n);read(m);read(q);
    read(u);read(v);read(t);
    for(register int i=1;i<=n;++i) read(a[0][i]);
    a[0][0]=n;
    top[0]=top[1]=top[2]=1;
    sort(a[0]+1,a[0]+n+1,cmp);
    for(register int i=1;i<=m;++i)
    {
        int maxx=(top[0]>n);
        if(a[maxx][top[maxx]]<a[1][top[1]]&&top[1]<=a[1][0]) maxx=1;
        if(a[maxx][top[maxx]]<a[2][top[2]]&&top[2]<=a[2][0]) maxx=2;
        int len=a[maxx][top[maxx]++]+(i-1)*q;
        int L=(long long)u*len/v;
        int R=len-L;
        a[1][++a[1][0]]=L-q*i;
        a[2][++a[2][0]]=R-q*i;
        if(i%t==0) printf("%d ",len);
    }
    printf("\n");
    int l=top[0],r=top[1];
    while(l<=a[0][0]&&r<=a[1][0])
    {
        if(a[0][l]>a[1][r]) b[++b[0]]=a[0][l++];
        else b[++b[0]]=a[1][r++];
    }
    while(l<=a[0][0]) b[++b[0]]=a[0][l++];
    while(r<=a[1][0]) b[++b[0]]=a[1][r++];
    l=1;r=top[2];
    while(l<=b[0]&&r<=a[2][0])
    {
        if(b[l]>a[2][r]) c[++c[0]]=b[l++];
        else c[++c[0]]=a[2][r++];
    }
    while(l<=b[0]) c[++c[0]]=b[l++];
    while(r<=a[2][0]) c[++c[0]]=a[2][r++];
    for(int i=t;i<=n+m;i+=t) printf("%d ",c[i]+m*q);
    printf("\n");
    return 0;
}

Guess you like

Origin www.cnblogs.com/Chtholly/p/11347779.html