Cod sursa(job #655164)

Utilizator nandoLicker Nandor nando Data 1 ianuarie 2012 16:50:30
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <bitset>
#include <cstdio>
using namespace std;


FILE* fout = fopen("ssnd.out","w");

#define MAXP 1000005
#define MOD 9973

typedef long long int64;

//<parsing>
FILE* fin = fopen("ssnd.in","r");
const unsigned maxb = 8192;
char buf[maxb];
unsigned ptr = 0;

inline int64 getInt()
{
	int64 nr = 0;
	while (buf[ptr] < '0' || '9' < buf[ptr]) {
		if (++ptr >= maxb) {
			fread (buf, maxb, 1, fin), ptr = 0;
		}
	}

	while('0' <= buf[ptr] && buf[ptr] <= '9') {
		nr = nr * 10 + buf[ptr] - '0';
		if (++ptr >= maxb) {
			fread(buf, maxb, 1, fin), ptr = 0;
		}
	}
	return nr;
}
//</parsing>


int prim[80000],np = 0;
bitset<MAXP> era;

inline int64 pow(int64 a,int64 p){
	int64 x = a, r = 1;
	while (p) {
		if (p & 1) {
			r = (r * x) % MOD;
		}

		x = (x * x) % MOD, p >>= 1;
	}
	return r;
}

void ciur()
{
	for (int i = 1; ((i * i) << 1) + (i << 1) < MAXP; ++i){
		if(!era[i]){
			for(int j = ((i * i) << 1) + (i << 1);(j << 1) + 1 < MAXP; j += (i << 1) + 1){
				era[j] = true;
			}
		}
	}
	prim[np++] = 2;
	for(int i = 1;(i << 1) + 1< MAXP;i++){
		if(!era[i]){
			prim[np++]=(i << 1) + 1;
		}
	}
}

void doTest(int64 nr)
{
	int64 nd=1,sd=1,d=0,p=0,sp,n=nr;
	while(int64(prim[d])*int64(prim[d])<=nr){
		if(nr%prim[d]==0){
			p=0,sp=prim[d];
			while(n%prim[d]==0){
				p++,n/=prim[d],sp*=prim[d];
			}
			if(p!=0){
				nd=(nd*((p+1)%MOD))%MOD;
				sd=(((sd*((sp - 1) % MOD))%MOD)*(pow(prim[d]-1, MOD-2)))%MOD;
			}
		}
		d++;
	}

	if(n>1){
		nd=(nd*2)%MOD;
		sd=(((sd*((n*n - 1) % MOD))%MOD)*(pow(n-1, MOD-2)))%MOD;
	}

	fprintf(fout,"%lld %lld\n",nd,sd);
}

int main(){
	ciur();

	for(int i = 0, t = getInt();i < t; i++){
		doTest(getInt());
	}

	fclose(fin);
	fclose(fout);
	return 0;
}