Cod sursa(job #212842)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 7 octombrie 2008 11:01:39
Problema Frac Scor 50
Compilator c Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <stdio.h>
#include <stdlib.h>
#define N 1<<17
long long int n,k;
void scan(void){
	char buffer[32];
	int aux=0,poz=0,i;
	long long int tmp[4];
	freopen("frac.in","r",stdin);
	freopen("frac.out","w",stdout);
	scanf("%llu %llu",&n,&k);
	/*gets(buffer);
	for (i=0;buffer[i];++i)
		if (buffer[i]==' '){
			tmp[++poz]=aux;
			aux=0;
		}
		else{
			aux=aux*10+buffer[i]-'0';
		}
	tmp[++poz]=aux;
	n=tmp[1];k=tmp[2];*/
}	
int stack[N],check[N];
inline void check_it(int i){
	check[i]=1;
}
inline void push_in_stack(int i){
	stack[++stack[0]]=i;
}
int st[N];
inline void push_again(int i){
	st[++st[0]]=i;
}
void search_for_primes(void){
	int i;
	long long j,cln=n;
	push_in_stack(2);
	for (i=4;(long long)i*(long long)i<=n;i+=2)
		check_it(i);
	for (i=3;(long long)i*(long long)i<=n;i+=2)
		if (!check[i]){
			push_in_stack(i);
			for (j=(long long)i*(long long)i;j*j<(long long)N;j+=i)
				check_it((int )j);
		}
	for (i=1;i<=stack[0] && cln>1;++i){
		if (cln%stack[i]==0){
			push_again(stack[i]);
		}
		while (cln%stack[i]==0)
			cln/=stack[i];
	}
}
long long now;
int luate[64];
void valid(int k,long long x){
	int i,tma;
	long long rez=1,tmp;
	for (i=1;i<=k;++i){
		rez*=(long long)st[luate[i]];
	}
	now+=(long long)x/(long long)rez;
	tmp=(unsigned long long )((long long)x/(long long )rez);
}
void comb(int n,int step,int luat,int k,long long x){
	int i;
	if (step==n+1){
		if (luat==k)
			valid(k,x);
		return ;
	}
	luate[luat+1]=step;
	comb(n,step+1,luat+1,k,x);
	comb(n,step+1,luat,k,x);
}
long long f(long long x){
	long long s=0;
	int i;
	for (i=1;i<=st[0];++i){
		now=0;
		comb(st[0],1,0,i,x);
		//printf("\n");
		if (i%2==1)
			s+=(long long)now;
		else
			s-=(long long)now;
	}
	//fprintf(stderr,"%lld ",x);
	return x-s;
}
#define MAX 1LL<<63
void search(long long p,long long u,long long nr){
	long long m=((long long)p+u)>>1;
	while(p!=u)  {  
        m=((long long)p+u)/2;  
        if(nr<=f(m))  
            u=m;  
        else  
            p=m+1;		
    }  
	printf("%lld\n",p);
}
void solve(void){
	int i;
	search_for_primes();
	search(1,MAX,k);
}
void print(void){
	exit(0);
}
int main(void){
	scan();
	solve();
	print();
}