Cod sursa(job #67111)

Utilizator gigi_becaliGigi Becali gigi_becali Data 22 iunie 2007 16:12:28
Problema GFact Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.35 kb
#include<fstream.h>
#include<stdio.h>
#include<math.h>#include <stdlib.h>
#include <time.h>

using namespace std;

#define inc 1234567890u
#define mod &((1u<<31)-1)
#define ull unsigned long long

//a^(n-1) == 1 (MOD n)
//pow(a,n-1,n)
unsigned pow(unsigned x,unsigned put,unsigned MOD)
{
	unsigned tmp = x, ret = 1;
	while(put)
	{
		if(put&1) ret = ((ull)ret*tmp) % MOD;
		tmp = ((ull)tmp*tmp) % MOD;
		put >>= 1;
	}		
	return ret;
}	

unsigned test(unsigned n,unsigned s)
{
	#define tst(x) if(n == (n/x)*x && n != x)  return 0;	
	tst(2) tst(3) tst(5) tst(7) tst(11) tst(13) tst(17) tst(19)
	tst(23)	tst(29) tst(31) tst(37) tst(41) tst(43) tst(47) 
	tst(53) tst(59) tst(61) tst(67) tst(71) tst(73) tst(79) tst(83) 
	tst(89) tst(97) tst(101) 
	if(n <= 1) return 0;
	if(n <= 3) return 1;

	unsigned a;      
	while(s) 
	{
		do {a = (rand() % (n-1)) + 1;} while(a == 1);
		if(pow(a,n-1,n) != 1) return 0;
		--s;
	}	
	return 1;
}	

long long unsigned p;
long long unsigned q, b, nr;
long long unsigned a, v[10], ex;

void citire()
{
  ifstream in("gfact.in");
  in>>p>>q;
  in.close();
}

int prim(long x)
{
  if (x==2) return 1;
  if (x==1) return 0;
  if (x%2==0) return 0;
  for (long long unsigned d=3; d*d<=x; d+=2)
    if (x%d==0) return 0;
  return 1;
}

void descomp()
{
  int ok=1;b=p;
  for (long long unsigned  d=2; d<=p; d++)
    {
      if (p%d==0)
      {
	v[++nr]=d;
	ex=0;
	while (p%d==0) { p/=d; ex++;}
	if (test(p, 13)) { v[++nr]=p; ex=1; ok=0;}
      }
      if (ok==0) {p=v[nr]; break;}
    }    
}


void aflup()
{
  long long unsigned i, contor=0;
  
  i=p;
  while (contor<q)
   {
     long long unsigned j;
     j=i;
     if (j%p==0)
       while (j%p==0)
	 {
	   ++contor;
	   j/=p;
	 }
     i+=p;
   }
 
  printf("%llu",i-p);
  
}

void aflu()
{
  long long unsigned i, contor=0;
  
  i=v[nr];
  while (contor<q*ex)
   {
     long long unsigned j;
     j=i;
     if ((j/v[nr])*v[nr]==j)
       while (j%v[nr]==0)
	 {
	   contor++;
	   j/=v[nr];
	 }
     i+=v[nr];
   }
  //freopen("gfact.out","w",stdout);
  printf("%llu",i-v[nr]);
  
}

int main()
{
	srand(time(0));
	 //freopen("gfact.out","w",stdout);
	 freopen("gfact.out","w",stdout);
  citire();
  if (test(p,13)) aflup();
  else{
        descomp();
        aflu();
      }
  return 0;
}