Cod sursa(job #273244)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 8 martie 2009 13:10:05
Problema GFact Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
# include <stdio.h>
# include <math.h>

# define MAXP 15000
# define BAZA 1000000000


long int ciur[MAXP+1],ciurlen;
long int p,q;
long int fact[MAXP+1],factlen,rep[MAXP+1];
typedef long long int TIP;
TIP solp[MAXP+1],sol;

TIP max(TIP a, TIP b) {if (a>b) return a; return b;}

void citire()
{
     FILE *f=fopen("gfact.in","r");
     fscanf(f,"%ld%ld",&p,&q);
     fclose(f);
}

long int prim(long int a)
{
     long int i;
     for (i=1;i<=ciurlen&&ciur[i]*ciur[i]<=a;i++)
         if (a%ciur[i]==0) return 0;
     return 1;
}

void make_ciur()
{
     long int i,upper_bound=(long int)sqrt(p)+1;
     ciur[1]=2;
     ciurlen=1;
     for (i=3;i<=upper_bound;i+=2)
         {
         if (prim(i)) ciur[++ciurlen]=i;
         }
}

void factorizeaza_p()
{
     long int i;
     for (i=1;p!=1&&i<=ciurlen;i++)
         {
         if (p%ciur[i]==0)
            {
            fact[++factlen]=ciur[i];
            rep[factlen]=0;
            while (p%ciur[i]==0) 
                  {
                  p/=ciur[i];
                  rep[factlen]++;
                  }
            }
         }
     if (p!=1)
            {
            fact[++factlen]=p;
            rep[factlen]=1;
            }
}
           
void inmulteste_rep_q()
{
     long int i;
     for (i=1;i<=factlen;i++) rep[i]*=q;
}

long int puterea(long long int x, long int p)
{
     long int sol=0;
     while (x) {sol+=x/p;x/=p;}
     return sol;
}

long long int searchbin(long long int li, long long int lf,long int target, long int base)
{
     //printf("%ld:%ld\n",target,base);
     if (li>lf) return 0;
     long long int m=(li+lf)/2;
     long int pm=puterea(m,base),pm1=puterea(m-1,base);
     if (pm>=target&&pm1<target) return m;
     if (pm<target) return searchbin(m+1,lf,target,base);
     return searchbin (li,m-1,target,base);
}

void calculeaza()
{
     long int j,i;TIP aux;
     for (i=1;i<=factlen;i++) //pt fiecare factor prim
         {
         aux=(long long int)fact[i]*rep[i];
         if (rep[i]<=fact[i]) solp[i]=aux;
         else solp[i]=searchbin((long long int)fact[i],aux,rep[i],fact[i]);
         }
     //getchar();
}


void scrie_fisier()
{
     FILE *g=fopen("gfact.out","w");
     if (sol/BAZA) fprintf(g,"%lld",sol/BAZA);
     fprintf(g,"%lld\n",sol%BAZA);
     fclose(g);
}

void get_solution()
{
     sol=solp[1];
     long int i;
     for (i=2;i<=factlen;i++)
        sol=max(sol,solp[i]);
}

int main()
{
    //printf("%ld\n",sizeof(long long int));
    citire();
    psafe=p;
    make_ciur();
    factorizeaza_p();
    inmulteste_rep_q();
    calculeaza();
    get_solution();
    if (psafe==1) sol=1;
    scrie_fisier();
    return 0;
}