Cod sursa(job #206014)

Utilizator savimSerban Andrei Stan savim Data 4 septembrie 2008 10:19:01
Problema Descompuneri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <stdio.h>
#include <math.h>
#include <algorithm>

using namespace std;

#define maxl 3510

long long i,j,n,k,m,p,rad,cop,nr,ram;
long long prim[100],put[100],divi[maxl];
int c[maxl][maxl];

int poz(long long x)
{
    int p=0,q=m+1,r;
    while (p+1<q)
    {
        r=(p+q)/2;
        if (divi[r]<x) p=r;
        else if (divi[r]>x) q=r;
             else return r;
    }
}

void back_divi(long long p, long long val)
{
    long long i,t;

    if (p==m+1)
    {
        if (val>1)divi[++nr]=val;
        return;
    }
    
    for (i=0; i<=put[p]; i++)
    {
        if (!i) t=1;
        else t*=prim[p];
        back_divi(p+1,val*t);
    }
}


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

    scanf("%lld %lld",&n,&k);

    rad=(int)sqrt(n);cop=n;
    for (i=2; i<=rad; i+=2)
    {
        if (n%i==0)
        {
            prim[++m]=i;
            while (n%i==0) {n/=i;put[m]++;}
        }

        if (i==2) i--;
    }
    if (n>1) {prim[++m]=n;put[m]=1;}
    n=cop;

    back_divi(1,1);m=nr;
    sort(divi+1,divi+nr+1);

    /* c[i,j] = in cate moduri pot scrie divizorul i, astfel incat primul
                factor din scriere sa fie mai mare sau egal cu divi[j] */

    for (i=0; i<=m; i++)
        c[i][i]=1;
    for (i=2; i<=m; i++)
    {
        ram=1;
        for (j=i-1; j>=1; j--)
        {
            c[i][j]=c[i][j+1];

            if (divi[i]%divi[j]==0)
            {
                while (divi[ram]!=divi[i]/divi[j] && ram<=m)
                    ram++;
                c[i][j]+=c[ram][j];
            }
        }
    }

    printf("%d\n",c[m][1]);

    for (i=1; i<=m; i++)
    if (n%divi[i]==0)
    {
        nr=poz(n/divi[i]);

        if (n==divi[i])
        {
            printf("%lld\n",n);
            break;
        }
        if (c[nr][i]<k)
        {
            k-=c[nr][i];
        }
        else
        {
            printf("%lld ",divi[i]);
            n/=divi[i];i--;
        }
        if (n==1) break;
    }

    return 0;
}