Cod sursa(job #641564)

Utilizator vlad.doruIon Vlad-Doru vlad.doru Data 28 noiembrie 2011 20:43:33
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include <fstream>

using namespace std;

ifstream in("ssnd.in");
ofstream out("ssnd.out");

const int N=32000;
const int P=9973;

unsigned int v[N],bit[33],prime[10*N];
int nrprime;

inline bool viz(int x){
	int a,b;
	a=x/32;
	b=x%32;
	if(v[a]&bit[b])
		return true;
	return false;
}		

inline void marcheaza(int x){
	int a,b;
	a=x/32;
	b=x%32;
	v[a]=v[a]|bit[b];
}

void ciur(){
	int i,n;
	n=1000000;
	bit[0]=1<<31;
	for(i=1;i<=31;i++){
		bit[i]=(bit[i-1]>>1);
	}
	int j;
	for(i=3;i*i<=n;i+=2){
		if(viz(i)==false){
			for(j=i*i;j<=n;j+=i){
				marcheaza(j);
			}
		}
	}
	nrprime++;
	prime[nrprime]=2;
	for(i=3;i<=n;i+=2){
		if(viz(i)==false){
			nrprime++;
			prime[nrprime]=i;
		}
	}
}

inline int exprapid(int x,int n){
	int rez=1;
	x%=P;
	while(n!=0){
		if(n&1){
			rez=(rez*x)%P;
		}
		x=(x*x)%P;
		n>>=1;
	}
	rez=rez%P;
	return rez;
}

void sumdiv(long long x){
	int i,cx,div,nr=1,sum=1;
	cx=x;
	i=1;
	while(prime[i]<=x && i<=nrprime && prime[i]*prime[i]<=x){
		if(x%prime[i]){
			i++;
			continue;
		}
		div=0;
		while(!(x%prime[i])){
			div++;
			x/=prime[i];
		}
		nr=nr*(div+1);
		nr=nr%P;
		sum=(sum*(exprapid(prime[i],div+1)-1))%P;
		sum=(sum*(exprapid((prime[i]-1),P-2)))%P;
		i++;
	}
	if(x > 1) {
		nr*=2;
		sum=(sum*(x+1)%P);
	}
	out<<nr%P<<" "<<sum%P<<"\n";
}		

int main(){
	int t,i;
	long long x;
	in>>t;
	ciur();
	for(i=1;i<=t;i++){
		in>>x;
		sumdiv(x);
	}
	return 0;
}