Cod sursa(job #425785)

Utilizator laurpoppopescu laurentiu laurpop Data 26 martie 2010 09:06:37
Problema Descompuneri Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include<stdio.h>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
using namespace std;
FILE *f=fopen("desc.in","r");
FILE *g=fopen("desc.out","w");
long long divs[3001],n,k,nrdivs,i,j,p,x,y,u,m,w;
int a[3001][3001];

int cmp(const void  *a,const void  *b)
    {
       long long x = *((long long*)a);
       long long y = *((long long*)b);
       if (x < y)
          return -1;
       if (x == y)
          return 0;
      return 1;
 }
int fct(long long a, long long b){
	return a>b;
}
void divide(){
	long long  d;
	for(d=2;d*d<=n;d++)
		if(n%d==0){
			divs[0]++;
			divs[divs[0]]=d;
		}
nrdivs=divs[0];
for(d=1;d<=nrdivs;d++)
 if(n/divs[d]!=divs[d])
{ divs[0]++;
  divs[divs[0]]=n/divs[d];
}
divs[0]++;
divs[divs[0]]=n;
nrdivs=divs[0];
//qsort(divs+1, nrdivs, sizeof(long long),cmp);	
sort(divs+1,divs+nrdivs+1);

}

long long caut(long long y){
if(y==1)
return 1;
	p=2;
	u=nrdivs;
	while(p<=u){
		m=(p+u)/2;
		if(divs[m]>y)
		 u=m-1;
		else if(divs[m]<y)
			  p=m+1;
		else return m;}
return 0;	
}

long long caut1(long long y){
if(y==1)
return 0;
	p=2;
	u=nrdivs;
	while(p<=u){
		m=(p+u)/2;
		if(divs[m]>y)
		 u=m-1;
		else if(divs[m]<y)
			  p=m+1;
		else return m;}
return 0;	
}
/*void recons(int lvl,int k){
	if(lvl>=1){
	long long i=1;
   while(a[lvl][i]<k)
	   {   k-=a[lvl][i];
		   i++;
	  }
   recons(caut1(divs[lvl]/divs[i]),k);
   fprintf(g,"%lld ",divs[i]);
	}

}
*/
void recons(int k,int l){
	int i,p;
	if(n==1){
		 //fprintf(g,"%d ",n);
 			 return;}
	for(i=2;i<=nrdivs;i++)
	{ if(n==divs[i])
	{
		fprintf(g,"%d ",n);
		//recons(k,i+1,1);
		return;
	}
	else{
		if(n%divs[i]!=0) 
		 continue;
		p=caut(n/divs[i]);
		
	 if(a[p][i]>=k){
		
		 n=divs[i];
		 recons(k,i+1);
		  fprintf(g,"%d ",divs[p]);
	 }
	 else
		 if(k==0){
			 
 			 return;}
	 else
		 k=k-a[p][i];
		
	}
	
}
}
int main(){
	//citire
fscanf(f,"%lld%lld",&n,&k);
    //divsizorii lui n
divide();
    //initializam prima linie cu 1

//a[1][1]=1;
for(i=nrdivs;i>=1;i--) 
	  divs[i+1]=divs[i];
nrdivs++;
divs[1]=1;
divs[0]=nrdivs;
for(i=0;i<=nrdivs;i++)
	 a[1][i]=1;
for(i=2;i<=nrdivs;i++){
	for(j=1;j<=nrdivs;j++){
		a[i][j]=a[i][j-1]; //valoarea anterioara
		if(i>=j&&divs[i]%divs[j]==0) //daca se imparte
		{  y=divs[i]/divs[j]; //trebuie sa cautam pozitia divsizorului p
		   x=caut(y);
		   a[i][j]+=a[x][j];
		}
}
}

//reconstituire
fprintf(g,"%d\n",a[nrdivs][nrdivs]);	
recons(k,1);
//reconstruiere sol
/*w=nrdivs;i=1;
while(k>0&&w>0){
if(a[w][i] < k)
	 i++;
else { k-=a[w][i-1];
       fprintf(g,"%d ",divs[i]);
       w=caut1(divs[w]/divs[i]);
	   i=1;
}
}*/
return 0;
}