Cod sursa(job #2276248)

Utilizator cezar.plescaCezar Plesca cezar.plesca Data 4 noiembrie 2018 14:28:36
Problema Suma si numarul divizorilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include<stdio.h>
#include<math.h>
#include<vector>

using namespace std;

#define MAX_PRIME 1000000

bool notprimes[MAX_PRIME+1];
vector<int> primes;

long long v[1000];

vector<pair<long long,int>> primeDivs;

int NBPRIMES;

int m=9973;

void decomposition(long long n){
	int rad=sqrt((double)n);
	int exp;
	long long auxn;
	for(int i=0;i<NBPRIMES;i++){
		if(primes[i]>rad)
			break;
		auxn=n;
		exp=0;
		while((auxn%primes[i])==0){
			exp++;
			auxn/=primes[i];
		}
		if(exp>0){
			primeDivs.push_back(make_pair(primes[i],exp));
			rad=sqrt((double)auxn);
		}
	}
	if(primeDivs.empty()){
		primeDivs.push_back(make_pair(n,1));
		return;
	}
	if(auxn!=1){
		primeDivs.push_back(make_pair(auxn,1));
	}
}



int pmod(int x,int p){
	long long y,z;
	if(p==0)
		return 1;
	if(p & 1){
		y=pmod(x,p>>1);
		z=(y*y)%m;
		z=(z*x)%m;
	}
	else{
		y=pmod(x,p>>1);
		z=(y*y)%m;
	}
	return (int)z;
}

void euclid(long long a, long long b, long long *d, long long *x, long long *y){
    if (b == 0) {
        *d = a;
        *x = 1;
        *y = 0;
    } else {
        long long x0, y0;
        euclid(b, a % b, d, &x0, &y0);
        *x = y0;
        *y = x0 - (a / b) * y0;
    }
}

int main(){
	
	int T;

	FILE* f= fopen("ssnd.in","rt");
	FILE* g= fopen("ssnd.out","wt");

	// Ciurul lui Eratosthenes
	for(int i=2;i<=MAX_PRIME;i++){
		if(notprimes[i]==false){
			primes.push_back(i);
			for(int j=2*i;j<=MAX_PRIME;j+=i)
				notprimes[j]=true;
		}
	}

	NBPRIMES=primes.size();
	fscanf(f,"%d",&T);

	int nbdiv;
	int p,d;

	for(int i=0;i<T;i++){
		fscanf(f,"%lld",&v[i]);

		if(v[i]==1){
			fprintf(g,"1 1\n");
			continue;
		}

		primeDivs.clear();
		decomposition(v[i]);
		nbdiv=1;
		int l=primeDivs.size();

		int prod=1;
		for(int j=0;j<l;j++){
			p=primeDivs[j].first;
			d=primeDivs[j].second;
			nbdiv*=(d+1);
			if(((p-1)%m)==0){
				prod=(prod*(d+1))%m;
			}
			else{
				int a=pmod(p,d+1)-1;
				if(a<0)
					a+=m;
				long long d, x, y;
				if(p>2)
					euclid(p-1,m, &d, &x, &y);
				else
					x=1;
				x=x%m;
				if(x<0)
					x+=m;
				x=(x*a)%m;
				prod=(prod*x)%m;
			}
		}

		fprintf(g,"%d %d\n",nbdiv,prod);
	}

	fclose(g);
	fclose(f);
	return 0;
}