Codechef 2015年11月问题

EGRCAKE

(1)问题描述:

(2)要点:

(3)代码:

#include <stdio.h>

unsigned int gcd(unsigned int a,unsigned int b)
{
	if(a < b) return gcd(b,a);
	if(0 == b) return a;
	if(1 == b) return 1;
	return gcd(b,a%b);
}

int main()
{
	unsigned int nCases = 0;scanf("%d",&nCases);
	for(unsigned int iCases = 1;iCases <= nCases;++iCases)
	{
		unsigned int n = 0,m = 0;scanf("%d%d",&n,&m);
		unsigned int d = gcd(n,m);
		if(1 == d) printf("Yes\n");
		else printf("No %u\n",n/d);
	}
	return 0;
}


KFUNC

(1)问题描述:

(2)要点:注意到F(10) = F(1),F(11) = F(2),F(12) = F(3),....F(18) = F(9),且F(a+1) = F(F(a)+1),即这是一个1,2,3,...9的循环

(3)代码:


SMPLSUM

(1)问题描述:You're given many values of N; for each of them, compute N/gcd(N,1)+N/gcd(N,2)+...+N/gcd(N,N)

(2)要点:通过OEIS可以知道

(3)代码:

#include <stdio.h>
#include <assert.h>
#include <vector>
#include <algorithm>
using std::vector;
// 计算所有 <= maxn的数,factors[v]是v的一个素因子
static bool generate_factors(unsigned int maxn,vector<unsigned int>& factors)
{
	factors.clear();factors.resize(maxn+1,1);
	for(unsigned int p = 2;p <= maxn;++p)
	{
		if(1 != factors[p]) continue;
		if(p > maxn/p) continue;
		for(unsigned int v = p*p;v <= maxn;v += p) factors[v] = p;
	}
	return true;
}

static bool get_primes(unsigned int n,const vector<unsigned int>& factors,vector<unsigned int>& pfactors,vector<unsigned int>& pcounts)
{
	vector<unsigned int> primes;primes.reserve(10);
	unsigned int v = n;
	for(;1 != factors[v];)
	{
		unsigned int p = factors[v];
		primes.push_back(p);
		//for(;0 == (v%p);v /= p);
		v /= p;
	}
	if(0 == primes.size() || 1 != v) primes.push_back(v);
	std::sort(primes.begin(),primes.end());
	assert(primes.size() > 0);
	pfactors.clear();pfactors.reserve(primes.size());
	pfactors.push_back(primes[0]);pcounts.push_back(1);
	for(size_t i = 1;i < primes.size();++i)
	{
		if(primes[i] != primes[i-1]) { pfactors.push_back(primes[i]);pcounts.push_back(1); }
		else { ++pcounts[pcounts.size()-1]; }
	}
	return true;
}
// 计算p^2x - p^(2x-1) + p^(2x-2) - ... + 1,其中product = p^2x
unsigned long long get_sum(unsigned long long product,unsigned int p)
{
	if(1 == p) return 1;
	unsigned long long sum = 0;
	for(unsigned int i = 0;0 != product;++i)
	{
		if(i&1) sum -= product;
		else sum += product;
		product /= p;
	}
	return sum;
}

// 计算n/gcd(n,1) + n/gcd(n,2) + ... + n/gcd(n,n)
class CSeqA057660
{
	CSeqA057660(const CSeqA057660&);
	CSeqA057660& operator=(const CSeqA057660&);
public:
	CSeqA057660() { ; }
	~CSeqA057660() { ; }
public:
	static unsigned long long get_fast(unsigned int n,const vector<unsigned int>& factors,vector<unsigned long long>& values)
	{
		if(0 == values.size())
		{
			values.resize(factors.size(),0);
			for(size_t i = 0;i < factors.size();++i)
			{
				if(1 != factors[i]) continue;
				values[i] = (unsigned long long)(i)*(i-1)+1;
			}
		}
		if(0 != values[n]) return values[n];
		unsigned int p = factors[n];
		assert(1 != p);
		unsigned int v = n,count = 0;
		for(;0 == (v%p);v /= p);
		unsigned long long product = (unsigned long long)(n/v)*(n/v);
		unsigned long long ans = get_sum(product,p);
		ans *= get_fast(v,factors,values);
		values[n] = ans;
		return ans;
	}
};

int main()
{
	static const unsigned int maxn = 10000000;
	vector<unsigned int> factors;
	generate_factors(maxn,factors);
	vector<unsigned long long> values;
	unsigned int nCases = 0;
	scanf("%d",&nCases);
	for(unsigned int iCases = 1;iCases <= nCases;++iCases)
	{
		unsigned int n = 0;scanf("%d",&n);
		unsigned long long ans = CSeqA057660().get_fast(n,factors,values);
		printf("%llu\n",ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值