Cod sursa(job #73408)

Utilizator andrei.12Andrei Parvu andrei.12 Data 18 iulie 2007 14:46:48
Problema GFact Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int p, q, nr;
long long bmax, bi;
int wop(int a, int b){
	int s = 1;
	for (int i=1; i<=b; i++)
		s*=a;
	return s;
}
struct ches{
	int b, e;
};
ches v[1000];
int comp(const void*x, const void*y){
	ches xx=*(ches*)x, yy=*(ches*)y;
	int a1 = wop(xx.b, xx.e), a2 = wop(yy.b, yy.e);
	if (a1<a2) return -1;
	if (a1>a2) return 1;
	return 0;
}
int main()
{
	freopen("gfact.in","r",stdin);
	freopen("gfact.out","w",stdout);
	int i, sqr, k, p1;
	scanf("%d%d", &p, &q);
	sqr = sqrt(p);
	p1 = p;
	for (i=2;i<=sqr;i++)
		if (p1%i==0){
			v[++nr].b = i;
			k = 0;
			do{
				k++;
				p1/=i;
			}
			while (p1%i==0);
			v[nr].e = k;
		}
	if (p1!=1){
		v[++nr].b = p1;
		v[nr].e = 1;
	}
	/*
	qsort(v, nr+1, sizeof(v[0]), comp);
	bc = v[nr].b;
	ex = v[nr].e*q;
	rz = ex*(bc-1)+1;
	nn = 0;
	do{
		rz/=bc;
		nn++;
	}
	while (rz>bc);
	int s1, a;
	long long li = wop(bc, nn), ls = li*bc, pz, gs = 0;
	while (!gs){
		pz = (li+ls)/2;
		a = bc;
		s1 = 0;
		while (pz/a != 0){
			s1+=pz/a;
			a*=bc;
		}
		if (s1 < ex)
			li = pz+1;
		else
			if (s1 > ex)
				ls = pz-1;
			else{
				gs = pz;
				int se = 0;
				while (!se){
					gs--;
					a = bc;
					s1 = 0;
					while (gs/a != 0){
						s1+=gs/a;
						a*=bc;
					}
					if (s1 != ex)
						se = 1;
				}
			}
	}
	*/
	for (i=1; i<=nr; i++){
		int li = 1, ls =2*q*v[i].e, gs = 0, s, pz, a;
		while (!gs){
			pz = (li+ls)/2;
			bi = v[i].b*pz;
			a = v[i].b;
			s = 0;
			while (bi/a != 0){
				s+=bi/a;
				a*=v[i].b;
			}
			if (s > q*v[i].e)
				ls = pz-1;
			else
				if (s < q*v[i].e)
					li = pz+1;
				else{
					bi-=pz;
					a = v[i].b;
					s = 0;
					while (bi/a != 0){
						s+=bi/a;
						a*=v[i].b;
					}
					if (s < q*v[i].e){
						if (bi+pz > bmax)
							bmax = bi+pz;
						gs = 1;
					}						
				}
		}
	}
	printf("%lld\n", bmax);
	fclose(stdin);
	fclose(stdout);
	return 0;
}