Luo Gu P2897 [worms] problem solution

First analyze the meaning of the questions:

The title says is beginning to give you a lot of earthworms, and then gives you the number of times specified, and each time have come from inside the longest earthworm to cut a q times the original, and the other one is the original (1-- q) times, the two cut and put back. After completion of a predetermined number of times, then all of the remaining output earthworms in descending order, is Jiangzi QWQ

As can be seen, there is a very violent very simple way, the length of each of earthworms are placed in a large heap root (priority queue), and from 1 - m times each time taken up from the top of the stack (the first team) earthworms and follow the piece given u, v and then back into the large cut pile root (priority queues), and where a large root heap priority queue are sorted directly into them want only a few like, so violent m times. After the completion of m times, from the top of the heap (first team) output once every top of the heap (first team) number, then pop know heap empty (queue empty) ended.

Not so simple! ! ! ! ! !

Cut a worm in the worm while others will grow up! ! ! Immediately think of is to modify the interval, because of the emergence zone changes, but this interval is certain, it must be in addition to that of the largest, most can be only the hands and feet in the largest above that, after all, only one, so modify them is also a lot easier, you can not only increase every time record increase in the number of the last used together then that's how to do without it? May need to add by subtracting the number, this is very clever, you can add and the other as the same number, but also allows sorting is correct otherwise it will affect the other did not add sorting

Code

#include <the iostream> 
#include <cstdio> 
#include <Queue> the using namespace STD; 
The priority_queue < int > Q;
 int main () 
{ int n-, m, QQ, U, V, T;
 // n-: Number earthworm; m: conditions within m seconds; q: rest earthworms increased length   int qwq; 
    Scanf ( " % D% D% D% D% D% D " , & n-, & m, & QQ, & U, & V, & T);
     Double P; 
    P = U * 1.0 / V;
     for ( int I = . 1 ; I <= n-;++ i)
        scanf(

 
    
     
    {"%d",&qwq);
        q.push(qwq);
    }
    int jss = 0;
    while(m --) 
    {
        int awa = q.top() + jss * qq;
        jss ++;
        if(jss % t == 0)
            printf("%d ",awa);
        q.pop();
        int X1 = awa * p;
        int aa = X1 - jss * qq;
        int bb = (awa - X1) - jss * qq;
        q.push(aa);q.push(bb);
    }
    printf("\n");
    int js = 0;
    while(!q.empty())
    {
        js ++;
        if(js % t == 0)
            printf("%d ",q.top() + jss * qq);
        q.pop();
    }
    printf("\n");
    return 0;
}

 

But good is that only 85 points, three points are 1.2s, on a super Diudiu only need to look at optimizing just fine.

But how to optimize it?

In fact, here you can find a very obvious monotonicity, if you start the earthworms will then sorted before a worm cut out each greater than or equal to some two earthworm earthworm cut out of the back of a two earthworm earthworm, after all, before a certain greater than or equal that a back, cut it out of the two half-arrays and placed behind a corresponding cut out must also be greater than two can be set equal to three monotonic queue (or sort sorted array and then stored) per once cut too when they are looking for the biggest cut from three queues inside just fine

AC Code:

#include <the iostream> 
#include <cstdio> 
#include <algorithm>
 const  int Ml = 1E5 + . 5 ;
 const  int M2 = 8e6;
 the using  namespace STD;
 int A [Ml];
 int B [M2];
 int C [M2] ;
 BOOL CMP ( int X, int Y) 
{ 
    return X> Y; 
} 
int main () 
{ 
    int n-, m, QQ, U, V, T;
 // n-: number earthworm; m: m in the second condition; q: remaining earthworms increased length   
    int qwq; 
    Scanf ("%d%d%d%d%d%d",&n,&m,&qq,&u,&v,&t);
    a[n + 1] = -0x7fffffff;
    double p;
    p = u * 1.0 / v;
    for(int i = 1;i <= n;++ i)
        scanf("%d",&a[i]);
    sort(a + 1,a + n + 1,cmp);
    int js = 0;
    int ja = 1;
    int jb = 1,tb = 0;
    int jc = 1,tc = 0;
    int Max;
    int zuobiao;
    while(m --)
    {
        if(a[ja] >= b[jb] && a[ja] >= c[jc])
        {
            Max = a[ja];
            ja ++;
        }
        else
        if(b[jb] >= a[ja] && b[jb] >= c[jc])
        {
            Max = b[jb];
            jb ++;
        }
        else
        if(c[jc] >= a[ja] && c[jc] >= b[jb])
        {
            Max = c[jc];
            jc ++;
        }
        int awa = Max + js * qq;
        js ++;
        if(js % t == 0)
            printf("%d ",awa);
        int X1 = awa * p;
        b[++ tb] = X1 - js * qq;
        c[++ tc] = (awa - X1) - js * qq;
    }
    printf("\n");
    int ans = 0;
    for(int i = ja;i <= n;++ i)a[i] += qq * js;
    for(int i = jb;i <= tb;++ i)b[i] += qq * js;
    for(int i = jc;i <= tc;++ i)c[i] += qq * js;
    b[tb + 1] = -0x7fffffff;
    c[tc + 1] = -0x7fffffff;
    while(ja <= n || jb <= tb || jc <= tc)
    {
        ans ++;
        if(a[ja] >= b[jb] && a[ja] >= c[jc] && ja <= n)
        {
            if(ans % t == 0)
                printf("%d ",a[ja]);
            ja ++;
        }
        else
        if(b[jb] >= a[ja] && b[jb] >= c[jc] && jb <= tb)
        {
            if(ans % t == 0)
                printf("%d ",b[jb]);
            jb ++;
        }
        else
        if(c[jc] >= a[ja] && c[jc] >= b[jb] && jc <= tc)
        {
            if(ans % t == 0)
                printf("%d ",c[jc]);
            jc ++;
        }
    }
    printf("\n");
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/acioi/p/11324035.html