Cod sursa(job #1494063)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 30 septembrie 2015 17:44:15
Problema Suma si numarul divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <utility>
using namespace std;

constexpr int mod = 9973;

pair<int, int> euclid_extins(const int a, const int b){
	if(a < b){
		const auto tmp = euclid_extins(b, a);
		return {tmp.second, tmp.first}; }
	if(b == 0){
		return make_pair(1, 0); }
	else{
		// ax + by = d
		// ax - bx + by + bx = d
		// (a-b)x + b(x+y) = d
		// ax - (a/b)*bx + by + (a/b)*bx = d
		// (a%b)x + b(y + (a/b)x) = d
		const auto tmp = euclid_extins(a%b, b);
		return {tmp.first, tmp.second - (a/b) * tmp.first}; } }

int exp(int e, int x){
	int rez = 1;
	for( ; x; x/=2, e *= e, e %= mod){
		if(x&1){
			rez *= e;
			rez %= mod; } }
	return rez; }

int invers_modular(const int x){
	// x*y % mod = 1
	// x*y + mod*p = 1
	const auto tmp = euclid_extins(x, mod);
	return (tmp.first%mod+mod)%mod; }

vector<int> calc_primes(const int maxn){
	vector<int> primes;
	vector<bool> e_prim(maxn/2 + 1, true);
	primes.push_back(2);
	for(long long i = 3; i <= maxn; i += 2){
		if(e_prim[i/2]){
			primes.push_back(i);
			for(long long j = i*i; j <= maxn; j += 2*i){
				e_prim[j/2] = false; } } }
	return primes; }

void ssnd(long long a, int& nr_div, int& s_div){
	const static vector<int> primes = calc_primes(1000000);
	nr_div = s_div = 1;
	int s_div_sus = 1, s_div_jos = 1;
	for(const auto p : primes){
		if(p > a){
			break; }
		int n = 0;
		for( ; a%p == 0; a /= p, ++n);
		if(n > 0){
			nr_div *= (n+1);

			s_div_sus *= (exp(p, n+1) - 1);
			s_div_sus %= mod;
			s_div_jos *= (p-1);
			s_div_jos %= mod; } }
	s_div = (s_div_sus * invers_modular(s_div_jos))%mod; }

int main(){
	ifstream f("ssnd.in");
	ofstream g("ssnd.out");
	int t;
	f >> t;
	for(int i = 0; i < t; ++i){
		int x, nr_div, s_div;
		f >> x;
		ssnd(x, nr_div, s_div);
		g << nr_div << ' ' << s_div << '\n'; }
	return 0; }