Cod sursa(job #411464)

Utilizator AndreyPAndrei Poenaru AndreyP Data 4 martie 2010 21:57:12
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include<stdio.h>
#include<bitset>
#include<vector>
using namespace std;
#define ll long long
#define N 1000010
#define M 9973
#define pb push_back
bitset<N> e;
vector<int> p;
inline void ciur()
{
	p.pb(2);
	int i,i1;
	for(i=3; i*i<N; ++i,++i)
	{
		if(e[i>>1]==1)
			continue;
		p.pb(i);
		i1=i<<1;
		for(int j=i*i; j<N; j+=i1)
			e[j>>1]=1;
	}
	for(; i<N; ++i)
	{
		if(e[i>>1]==0)
			p.pb(i);
	}
}
inline int lgput(int b,int e)
{
	int b1=1;
	for(; e>0; e>>=1)
	{
		if((e&1)==1)
			b1=(b1*b)%M;
		b=(b*b)%M;
	}
	return b1;
}
inline int afla(int b,int e)
{
	b%=M;
	if(b==0)
		return 1;
	if(b==1)
		return e+1;
	int aux=lgput(b,e+1);
	if(aux==0)
		aux=M-1;
	else
		--aux;
	return (aux*lgput(b-1,M-2))%M;
}
inline void rezolva()
{
	ll n;
	//int n1;
	//scanf("%d",&n1);
	//n=(ll)n1;
	scanf("%lld",&n);
	int rez1=1,rez2=1;
	int ex=0;
	while((n&1LL)==0)
	{
		++ex;
		n>>=1;
	}
	if(ex!=0)
	{
		rez1=ex+1;
		rez2=(((1LL<<(ex+1))-1)%M);
	}
	for(size_t i=1,lim=p.size(); i<lim && (ll)p[i]*p[i]<=n; ++i)
	{
		if(n%p[i]==0)
		{
			ex=0;
			while(n%p[i]==0)
			{
				n/=p[i];
				++ex;
			}
			rez1*=(ex+1);
			rez2=(rez2*afla(p[i],ex))%M;
		}
	}
	if(n!=1)
	{
		rez1<<=1;
		n%=M;
		rez2=(rez2*((int)n+1))%M;
	}
	printf("%d %d\n",rez1,rez2);
}
int main()
{
	freopen("ssnd.in","r",stdin);
	freopen("ssnd.out","w",stdout);
	
	ciur();
	int T;
	scanf("%d",&T);
	for(; T; --T)
		rezolva();
	
	return 0;
}