Cod sursa(job #1014291)

Utilizator ELHoriaHoria Cretescu ELHoria Data 22 octombrie 2013 13:41:46
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <cstdio>

const int pmax = int(1e5);
int primes[pmax];
const int mod = 9973;
int r[mod];
char p[int(1e6)/16 + 2];

void sieve() {
	int n = int(1e6);
	for(int i = 1;((i*i)<<1) + (i<<1) <= n;i++) {
		if((p[i>>3] & (1<<(i & 7))) == 0) {
			for(int j = ((i*i)<<1) + (i<<1);(j<<1) + 1 <= n;j += (i<<1) + 1) {
				p[j>>3] |= 1<<(j & 7);
			}
		}
	}
	int num = 1;
	primes[0] = 2;
	for(int i = 1;(i<<1) + 1 <= n;i++) {
		if((p[i>>3] & (1<<(i & 7))) == 0) {
		//	printf("%d\n",2*i + 1);
			primes[num++] = (i<<1) + 1;
		}
	}
//	printf("%d\n",num);
}

void computeRing() {
	r[1] = 1;
	for(int i = 2;i < mod;i++) {
		r[i] = (mod - (mod/i)*r[mod%i]%mod)%mod;	
	}
}

void solve(long long n) {
	long long divisorsNumber = 1;
	long long divisorsSum = 1;
	for(int i = 0;1ll*primes[i]*primes[i] <= n;i++) {
		if(n%primes[i] == 0) {
			int num = primes[i]%mod;
			int value = num;
			int power = 0;
			do {
				n /= primes[i];
				power++;
				value = 1ll*value*num%mod;
			} while(n%primes[i] == 0);
			divisorsNumber *= (power + 1);
			divisorsSum = (1ll*divisorsSum*(value - 1 + mod)%mod)*r[num - 1 < 0 ? mod - 1 : num - 1]%mod;
		}
	}
	if(n > 1) {
		divisorsNumber *= 2ll;
		divisorsSum = 1ll*divisorsSum*(n + 1)%mod;
	}
	printf("%lld %lld\n",divisorsNumber,divisorsSum);
}


int main()
{
    freopen("ssnd.in","r",stdin);
    freopen("ssnd.out","w",stdout);
	sieve();
	computeRing();
	int T;
	long long n;
	for(scanf("%d",&T);T;T--) {
		scanf("%lld",&n);
		solve(n);
	}
    return 0;
}