Cod sursa(job #547551)

Utilizator CipaFlorescu Ciprian Cipa Data 6 martie 2011 14:33:54
Problema Principiul includerii si excluderii Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include<vector>
#include<cstdio>
#include<cmath>
using namespace std;

vector<bool> ciur;
vector<int> primeNos;
vector<int> stack;

int count = 0;
long long a,b;
int size;

void mark(int i, long long n)
{
	int j = i;
	while(j<=n)
	{
		ciur[j] = 0;
		j += i;
	}
}

void initialize_ciur()
{
	for(long long i=0;i<ciur.size();i++)
		ciur[i] = 1;
}


void gen_ciur()
{
	
	int i=2;
	long long k = sqrt(b)+1;
	ciur.clear();
	ciur.resize(k+5,1);
	initialize_ciur();
	primeNos.clear();
	
	while(i<=k)
	{
		if(ciur[i] &&  b % i == 0)
		{	
			mark(i,k);
			primeNos.push_back(i);
		}
		++i;
	}
	
	if(!primeNos.size())
		primeNos.push_back(b);
}
void compute_primes()
{
	primeNos.clear();
	long long n = b;
	int i=2,s=sqrt(b)+1;
	while(n>1&&i<=s)
	{
		if(n%i==0)
		{	
			primeNos.push_back(i);
			while(n%i==0)
				n/=i;
		}
		i++;
	}
	if(n>1)
		primeNos.push_back(n);
}

int put_element(int i)
{
	if(i>=size)
		return 0;
	
	for(int j = 0;j<size;++j)
		if(primeNos[j]>stack[i])
			return primeNos[j];
	
	return 0;
}

void add(int n)
{
	long long sum = 1;
	for(int i = 0;i<=n;++i)
	{	
		//printf("%d,",stack[i]);
		sum *= stack[i];
	}
	//printf("\n");
	if(n%2)
		count -= a/sum;
	else
		count += a/sum;
		
	//printf(" -- %llu, %d\n",sum,count);
}

void back(int i)
{
	int p = put_element(i);
	while(p)
	{
		stack[i] = p;
		add(i);
		if(i<size-1)
		{
			stack[i+1]=stack[i];
			back(i+1);
		}
		p = put_element(i);
	}
}
	
void compute()
{
	//long long a,b;
	count = 0;
	scanf("%lld %lld",&a,&b);
	compute_primes();
	//gen_ciur();
	stack.clear();
	size=primeNos.size();
	//printf("size::%d\n",size);imeNos[i]);
	stack.resize(size,0);
	stack[0]=0;
	back(0);
	
	printf("%lld\n",a-count);
	

}

int main()
{
	freopen("pinex.in","r",stdin);
	freopen("pinex.out","w",stdout);
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		compute();
		
	return 0;
}