Cod sursa(job #66770)

Utilizator vrajalaMihai Viteazu, razboinicu luminii vrajala Data 21 iunie 2007 01:09:12
Problema Descompuneri Scor 8
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <stdio.h>
#define MaxDiv 257
#define MaxFact 10

int K,nr[MaxFact];
long long N,div[MaxDiv],fact[MaxFact],d[MaxDiv][MaxDiv];

void descompunere(long long N)
{
long long d;
if (N%2==0)
   {
   fact[++fact[0]]=2;
   while (N%2==0)
         {
         N/=2;
         ++nr[fact[0]];
         }
   }
d=3;
while (d<=N/2)
      {
       if (N%d==0)
          {
          fact[++fact[0]]=d;
          while (N%d==0)
                {
                N/=d;
                ++nr[fact[0]];
                }
          }
      d+=2;
      }
if (N>1)
   {
   fact[++fact[0]]=N;
   ++nr[fact[0]];
   }
}

void divizori(long long S,int lvl)
{
int i;
if (lvl>fact[0])
   {
    div[++div[0]]=S;
    return;
   }
divizori(S,lvl+1);
for (i=1;i<=nr[lvl];++i)
    {
     S*=fact[lvl];
     divizori(S,lvl+1);
    }
}

void qsort(int l,int r)
{
int i,j;
long long m,aux;
i=l;
j=r;
m=div[(l+r)/2];
while (i<=j)
      {
      while (div[i]<m) ++i;
      while (div[j]>m) --j;
      if (i<=j)
         {
          aux=div[i];
	  div[i]=div[j];
          div[j]=aux;
          ++i;
          --j;
         }
      }
if (i<r) qsort(i,r);
if (l<j) qsort(l,j);
}

void dothedamnthing()
{
 int i,j,last;
 for (i=1;i<=div[0];++i)
	d[1][i]=1;
 for (i=2;i<=div[0];++i)
     {
     last=i-1;
     for (j=2;j<=i;++j)
       {
       d[i][j]+=d[i][j-1];
       if (div[i]%div[j]==0)
	 {
	 while (div[last]!=div[i]/div[j])
	       --last;
	 d[i][j]+=d[last][j];
	 }
       }
     for (j=i+1;j<=div[0];++j)
	d[i][j]=d[i][j-1];
     }
}

void reconstituie()
{
int poz=2,last;
last=div[0];
while (N>1)
		{
		 //indice N/div[poz]
		 while (N%div[poz]!=0) ++poz;
		 while (div[last]!=N/div[poz])
			--last;
		 if ((last!=1)&&(d[last][poz]<K))
				{
				K-=d[last][poz];
				++poz;
				}
			else
				{
				printf("%lld ",div[poz]);
				N/=div[poz];
				}
	}
}

int main()
{
 freopen("desc.in","r",stdin);
 scanf("%lld %d",&N,&K);
 fclose(stdin);
 descompunere(N);
 divizori(1,1);
 qsort(1,div[0]);
 dothedamnthing();
 freopen("desc.out","w",stdout);
 printf("%lld\n",d[div[0]][div[0]]);
 reconstituie();
 fclose(stdout);
 return 0;
}