Cod sursa(job #585926)

Utilizator DraStiKDragos Oprica DraStiK Data 30 aprilie 2011 12:42:14
Problema NumMst Scor 4
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 2.32 kb
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
using namespace std;

#define MAX 10000005
#define DIM 4005


int ant_0[DIM],ant_1[DIM],prim[DIM],start[DIM];
double bst_0[DIM],bst_1[DIM],lg2[DIM];
bitset <MAX> viz,ok;
int oldN,N,P;

void read ()
{
    int i,j;

    scanf ("%d",&N);

    oldN=N;
    if (!(N&1))
        N=2;

    prim[++P]=2;
    for (i=3; i<=N; i+=2)
        if (!viz[i])
        {
            if (!(N%i))
                N=i;

            prim[++P]=i;
            for (j=3*i; j<=N; j+=(i<<1))
                viz[j]=1;
        }
}

void solve ()
{
    int i,j,val;

    if (N==2)
    {
        printf ("%d %d",oldN>>1,oldN>>1);
        return ;
    }

    if (N==3)
    {
        printf ("%d %d",oldN/3,2*oldN/3);
        return ;
    }


    for (i=2; i<=N; ++i)
        lg2[i]=log (i);

    val=0; ok[0]=1;
    for (i=1; i<=P; ++i)
    {
        for (j=val; j>0; --j)
            if (ok[j] && j+prim[i]<=N && !ok[j+prim[i]])
            {
                bst_0[j+prim[i]]=bst_0[j]+lg2[prim[i]];
                ant_0[j+prim[i]]=prim[i];

                bst_1[j+prim[i]]=bst_0[j]+lg2[prim[i]];
                ant_1[j+prim[i]]=prim[i];

                ok[j+prim[i]]=1;
                val=max (val,j+prim[i]);
            }

        if (ok[j] && j+prim[i]<=N && !ok[j+prim[i]])
        {
            bst_0[j+prim[i]]=bst_0[j]+lg2[prim[i]];
            ant_0[j+prim[i]]=prim[i];

            ok[j+prim[i]]=1;
            val=max (val,j+prim[i]);
        }
    }

    for (i=1; i<=N; ++i)
        if (bst_0[i-1]>bst_0[i])
        {
            start[i]=start[i-1];
            bst_1[i]=bst_1[i-1];
            bst_0[i]=bst_0[i-1];
        }
        else
            start[i]=i;

    val=start[N];
    if (!bst_1[val])
    {
        for ( ; !ok[val]; --val);
        printf ("%d ",(N-val)*(oldN/N));

        for ( ; val; val-=ant_0[val])
            printf ("%d ",ant_0[val]*(oldN/N));
    }
    else
    {
        printf ("%d ",ant_1[val]*(oldN/N));

        for (val-=ant_1[val]; val; val-=ant_0[val])
        printf ("%d ",ant_0[val]*(oldN/N));
    }
}

int main ()
{
    freopen ("nummst.in","r",stdin);
    freopen ("nummst.out","w",stdout);

    read ();
    solve ();

    return 0;
}